Merge branch 'apps_4_test' of https://e.coding.net/yilidev/yilipalkaifa/apps into apps_4_test

This commit is contained in:
zhaol 2025-07-14 15:36:51 +08:00
commit f477f687c1
64 changed files with 13468 additions and 24 deletions

View File

@ -116,7 +116,12 @@
<en><![CDATA[Process.Framework]]></en>
<big5><![CDATA[流程架构]]></big5>
</item>
<item key="process">
<item key="freedom.allmethod">
<cn><![CDATA[自由模型]]></cn>
<en><![CDATA[freedom.AllMethod]]></en>
<big5><![CDATA[自由模型]]></big5>
</item>
<item key="process">
<cn><![CDATA[流程制度]]></cn>
<en><![CDATA[Process]]></en>
<big5><![CDATA[流程制度]]></big5>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,44 @@
package com.actionsoft.apps.coe.pal;
import com.actionsoft.apps.coe.pal.pal.repository.designer.dto.VersionCompareDTO;
import com.actionsoft.apps.coe.pal.pal.repository.designer.dto.VersionListDTO;
import com.actionsoft.apps.coe.pal.pal.repository.designer.web.CoeDesignerVersionWeb;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.server.bind.annotation.Controller;
import com.actionsoft.bpms.server.bind.annotation.Mapping;
/**
* @author oYang
* @Description 设计器-流程版本对比 控制类
* @createTime 2024年07月29日 11:04:00
*/
@Controller
public class CoEDesignerVersionController {
/**
* 设计器版本列表
*
* @param uc 用户上下文
* @param wsId 资产库Id
* @param teamId 小组Id
* @param id 模型Id
* @return 模型版本列表
*/
@Mapping("com.actionsoft.apps.coe.pal_pl_repository_designer_version_list")
public String designerVersionList(UserContext uc, String wsId, String teamId, String id) {
VersionListDTO versionListDTO = new VersionListDTO(wsId, teamId, id);
return new CoeDesignerVersionWeb(uc).getVersionList(versionListDTO);
}
/**
* 设计器版本对比
*
* @param uc 用户上下文
* @param wsId 资产库Id
* @return 模型版本对比页面
*/
@Mapping("com.actionsoft.apps.coe.pal_pl_repository_designer_version_compare")
public String designerVersionCompare(UserContext uc, String wsId, String teamId, String compareVerId, String curId) {
VersionCompareDTO versionCompareDTO = new VersionCompareDTO(wsId, teamId, compareVerId, curId);
return new CoeDesignerVersionWeb(uc).designerVersionCompare(versionCompareDTO);
}
}

View File

@ -3050,9 +3050,9 @@ public class CoEPALController {
* @return
*/
@Mapping("com.actionsoft.apps.coe.pal_processlevel_create_method_list")
public String getPalProcessLevelCreateMethodList(UserContext me, String category, String methodId) {
public String getPalProcessLevelCreateMethodList(UserContext me, String category, String methodId , String fileId) {
CoeProcessLevelWeb web = new CoeProcessLevelWeb(me);
return web.getPalProcessLevelCreateMethodList(category, methodId);
return web.getPalProcessLevelCreateMethodList(category, methodId,fileId);
}
/**

View File

@ -0,0 +1,56 @@
package com.actionsoft.apps.coe.pal.components.model;
/**
* 密级实体类
*/
public class PALSecurityLevelModel {
/**
* 密级code
*/
private String code;
/**
* 密级名称
*/
private String name;
/**
* 密级颜色
*/
private String color;
public PALSecurityLevelModel() {
}
public PALSecurityLevelModel(String code, String name, String color) {
this.code = code;
this.name = name;
this.color = color;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}

View File

@ -0,0 +1,133 @@
package com.actionsoft.apps.coe.pal.pal.method.cache;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import com.actionsoft.apps.coe.pal.pal.method.cache.index.PALBasicMethodCacheIndex1;
import com.actionsoft.apps.coe.pal.pal.method.cache.index.PALBasicMethodCacheIndex2;
import com.actionsoft.apps.coe.pal.pal.method.cache.index.PALBasicMethodCacheIndex3;
import com.actionsoft.apps.coe.pal.pal.method.model.PALBasicMethodModel;
import com.actionsoft.apps.resource.plugin.profile.CachePluginProfile;
import com.actionsoft.bpms.commons.cache.Cache;
import com.actionsoft.bpms.commons.cache.CacheManager;
/**
* 建模方法基础信息缓存Cache
*/
public class PALBasicMethodCache extends Cache<String, PALBasicMethodModel> {
public PALBasicMethodCache(CachePluginProfile configuration) {
super(configuration);
registeIndex(PALBasicMethodCacheIndex1.class, new PALBasicMethodCacheIndex1()); // methodId-wsId
registeIndex(PALBasicMethodCacheIndex2.class, new PALBasicMethodCacheIndex2()); // wsId
registeIndex(PALBasicMethodCacheIndex3.class, new PALBasicMethodCacheIndex3()); // methodId
}
/**
* getCache
*
* @return
*/
public static PALBasicMethodCache getCache() {
return CacheManager.getCache(PALBasicMethodCache.class);
}
/**
* put
*/
public static void putModel(PALBasicMethodModel model) {
putModel(model, true);
}
public static void putModel(PALBasicMethodModel model, boolean notifyCluster) {
getCache().put(model.getId(), model, notifyCluster);
}
/**
* 根据建模方法Id和资产库Id
*
* @param methodId 建模方法Id
* @param wsId 资产库Id
* @return
*/
public static PALBasicMethodModel getModelByMethodIdAndWsId(String methodId, String wsId) {
return getCache().getByIndexSingle(PALBasicMethodCacheIndex1.class, methodId + "-" + wsId);
}
/**
* 获取全部建模方法基础信息List
*
* @return
*/
public static List<PALBasicMethodModel> getAllBasicMethodModel() {
Iterator<PALBasicMethodModel> iterator = getCache().iterator();
return iteratorToList(iterator);
}
/**
* 根据资产库获取该资产库下全部建模方法基础信息List
*
* @return
*/
public static List<PALBasicMethodModel> getAllBasicMethodModel(String wsId) {
Iterator<PALBasicMethodModel> iterators = getCache().getByIndex(PALBasicMethodCacheIndex2.class, wsId);
return iteratorToList(iterators);
}
/**
* 根据appId获取该appId下全部建模方法
*
* @param appId 应用id
* @return methodIds
*/
public static List<String> getMethodIdByAppId(String appId) {
List<PALBasicMethodModel> methodModels = getAllBasicMethodModel();
return methodModels.stream().filter(model -> appId.equals(model.getAppId())).map(PALBasicMethodModel::getMethodId).distinct().collect(Collectors.toList());
}
/**
* 根据id删除建模方法基础信息
*
* @param methodId
*/
public static void removeById(String methodId) {
getCache().removeIndexByKey(PALBasicMethodCacheIndex3.class, methodId);
}
/**
* 清除全部建模方法基础信息
*/
public static void removeAllBasicMethodModel() {
List<PALBasicMethodModel> list = getAllBasicMethodModel();
if (list != null && list.size() > 0) {
for (PALBasicMethodModel model : list) {
getCache().remove(model.getId());
}
}
}
/**
* 清除资产库建模方法缓存
*
* @param wsId 资产库id
*/
public static void removeByWsId(String wsId) {
getCache().removeIndexByKey(PALBasicMethodCacheIndex2.class, wsId);
}
/**
* 清除资产库建模方法缓存
*
* @param wsId 资产库Id
* @param methodId 建模方法Id
*/
public static void removeByWsIdAndMethodId(String wsId, String methodId) {
getCache().removeIndexByKey(PALBasicMethodCacheIndex1.class, methodId + "-" + wsId);
}
@Override
protected void load() {
}
}

View File

@ -0,0 +1,156 @@
package com.actionsoft.apps.coe.pal.pal.method.cache;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.actionsoft.apps.coe.pal.pal.method.cache.index.PALMethodSchemaCacheIndex1;
import com.actionsoft.apps.coe.pal.pal.method.cache.index.PALMethodSchemaCacheIndex2;
import com.actionsoft.apps.coe.pal.pal.method.cache.index.PALMethodSchemaCacheIndex3;
import com.actionsoft.apps.coe.pal.pal.method.cache.index.PALMethodSchemaCacheIndex4;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodSchemaModel;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodShapeSchemaModel;
import com.actionsoft.apps.resource.plugin.profile.CachePluginProfile;
import com.actionsoft.bpms.commons.cache.Cache;
import com.actionsoft.bpms.commons.cache.CacheManager;
import com.actionsoft.i18n.I18nRes;
/**
* 形状定义schema cache
*
* @author sunlianhui
*/
public class PALMethodSchemaCache extends Cache<String, PALMethodSchemaModel> {
public PALMethodSchemaCache(CachePluginProfile configuration) {
super(configuration);
registeIndex(PALMethodSchemaCacheIndex1.class, new PALMethodSchemaCacheIndex1()); // methodId
registeIndex(PALMethodSchemaCacheIndex2.class, new PALMethodSchemaCacheIndex2()); // methodId-lang
registeIndex(PALMethodSchemaCacheIndex3.class, new PALMethodSchemaCacheIndex3()); // methodId-wsId-lang
registeIndex(PALMethodSchemaCacheIndex4.class, new PALMethodSchemaCacheIndex4()); // wsId
}
/**
* getCache
*
* @return
*/
public static PALMethodSchemaCache getCache() {
return CacheManager.getCache(PALMethodSchemaCache.class);
}
/**
* getModel
*
* @param id
* @return
*/
public static PALMethodSchemaModel getModelById(String id) {
return getCache().get(id);
}
public static List<PALMethodSchemaModel> getModelListByMethodId(String methodId) {
return iteratorToList(getCache().getByIndex(PALMethodSchemaCacheIndex1.class, methodId));
}
public static PALMethodSchemaModel getModelListByMethodIdAndLang(String methodId, String lang) {
return getCache().getByIndexSingle(PALMethodSchemaCacheIndex2.class, methodId + "-" + lang);
}
public static PALMethodSchemaModel getModelListByMethodIdAndLangAndWsId(String methodId, String lang, String wsId) {
return getCache().getByIndexSingle(PALMethodSchemaCacheIndex3.class, methodId + "-" + wsId + "-" + lang);
}
/**
* 获取图元是否允许出现复制Map
*
* @param wsId 资产库id
* @param methodId 建模方法Id
* @return map
*/
public static Map<String, Boolean> shapeAllowOccurrence(String wsId, String methodId) {
PALMethodSchemaModel schemaModel = getModelListByMethodIdAndLangAndWsId(methodId, I18nRes.getUserLanguage(), wsId);
if (schemaModel != null) {
List<PALMethodShapeSchemaModel> shapeSchemaList = schemaModel.getShapeSchemaList();
return shapeSchemaList.stream().collect(Collectors.toMap(PALMethodShapeSchemaModel::getKey, PALMethodShapeSchemaModel::isAllowOccurrence, (existingValue, newValue) -> existingValue));
}
return new HashMap<>();
}
/**
* 根据形状key值获取形状
*
* @param wsId 资产库Id
* @param lang 语言
* @param methodId 建模方法Id
* @param shapeKey 形状key
* @return 形状模型
*/
public static PALMethodShapeSchemaModel getShapeByKey(String wsId, String lang, String methodId, String shapeKey) {
PALMethodSchemaModel schemaModel = getModelListByMethodIdAndLangAndWsId(methodId, lang, wsId);
List<PALMethodShapeSchemaModel> shapeSchemaList = schemaModel.getShapeSchemaList();
return shapeSchemaList.stream().filter(shape -> {
return shape.getKey().equals(shapeKey);
}).findFirst().orElse(null);
}
/**
* put
*/
public static void putModel(PALMethodSchemaModel model) {
putModel(model, true);
}
public static void putModel(PALMethodSchemaModel model, boolean notifyCluster) {
if (model != null) {
getCache().put(model.getId(), model, notifyCluster);
}
}
/**
* 根据id删除属性定义
*
* @param id
*/
public static void removeModelById(String id) {
getCache().remove(id);
}
public static void removeByMethodId(String methodId) {
List<PALMethodSchemaModel> list = getModelListByMethodId(methodId);
if (list != null) {
for (PALMethodSchemaModel model : list) {
removeModelById(model.getId());
}
}
}
public static void removeByMethodIdAndWsId(String methodId, String wsId) {
List<PALMethodSchemaModel> list = getModelListByMethodId(methodId);
if (list != null) {
for (PALMethodSchemaModel model : list) {
if (model.getWsId().equals(wsId))
removeModelById(model.getId());
}
}
}
public static void removeAll() {
Iterator<PALMethodSchemaModel> iterator = getCache().iterator();
while (iterator.hasNext()) {
PALMethodSchemaModel next = iterator.next();
getCache().remove(next.getId());
}
}
public static void removeByWsId(String wsId) {
getCache().removeIndexByKey(PALMethodSchemaCacheIndex4.class, wsId);
}
@Override
protected void load() {
}
}

View File

@ -0,0 +1,11 @@
package com.actionsoft.apps.coe.pal.pal.method.cache.index;
import com.actionsoft.apps.coe.pal.pal.method.model.PALBasicMethodModel;
import com.actionsoft.bpms.commons.cache.ListValueIndex;
public class PALBasicMethodCacheIndex1 extends ListValueIndex<String, PALBasicMethodModel> {
@Override
public String key(PALBasicMethodModel t) {
return t.getMethodId() + "-" + t.getWsId();
}
}

View File

@ -0,0 +1,11 @@
package com.actionsoft.apps.coe.pal.pal.method.cache.index;
import com.actionsoft.apps.coe.pal.pal.method.model.PALBasicMethodModel;
import com.actionsoft.bpms.commons.cache.ListValueIndex;
public class PALBasicMethodCacheIndex2 extends ListValueIndex<String, PALBasicMethodModel> {
@Override
public String key(PALBasicMethodModel t) {
return t.getWsId();
}
}

View File

@ -0,0 +1,11 @@
package com.actionsoft.apps.coe.pal.pal.method.cache.index;
import com.actionsoft.apps.coe.pal.pal.method.model.PALBasicMethodModel;
import com.actionsoft.bpms.commons.cache.ListValueIndex;
public class PALBasicMethodCacheIndex3 extends ListValueIndex<String, PALBasicMethodModel> {
@Override
public String key(PALBasicMethodModel t) {
return t.getMethodId();
}
}

View File

@ -0,0 +1,14 @@
package com.actionsoft.apps.coe.pal.pal.method.cache.index;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodSchemaModel;
import com.actionsoft.bpms.commons.cache.ListValueIndex;
/**
* 以methodId建立索引
*/
public class PALMethodSchemaCacheIndex1 extends ListValueIndex<String, PALMethodSchemaModel> {
@Override
public String key(PALMethodSchemaModel palMethodSchemaModel) {
return palMethodSchemaModel.getMethodId();
}
}

View File

@ -0,0 +1,14 @@
package com.actionsoft.apps.coe.pal.pal.method.cache.index;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodSchemaModel;
import com.actionsoft.bpms.commons.cache.SingleValueIndex;
/**
* 以methodId-lang建立索引
*/
public class PALMethodSchemaCacheIndex2 extends SingleValueIndex<String, PALMethodSchemaModel> {
@Override
public String key(PALMethodSchemaModel palMethodSchemaModel) {
return palMethodSchemaModel.getMethodId() + "-" + palMethodSchemaModel.getLang();
}
}

View File

@ -0,0 +1,11 @@
package com.actionsoft.apps.coe.pal.pal.method.cache.index;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodSchemaModel;
import com.actionsoft.bpms.commons.cache.ListValueIndex;
public class PALMethodSchemaCacheIndex3 extends ListValueIndex<String, PALMethodSchemaModel> {
@Override
public String key(PALMethodSchemaModel model) {
return model.getMethodId() + "-" + model.getWsId() + "-" + model.getLang();
}
}

View File

@ -0,0 +1,14 @@
package com.actionsoft.apps.coe.pal.pal.method.cache.index;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodSchemaModel;
import com.actionsoft.bpms.commons.cache.ListValueIndex;
/**
* 以methodId建立索引
*/
public class PALMethodSchemaCacheIndex4 extends ListValueIndex<String, PALMethodSchemaModel> {
@Override
public String key(PALMethodSchemaModel palMethodSchemaModel) {
return palMethodSchemaModel.getWsId();
}
}

View File

@ -0,0 +1,10 @@
package com.actionsoft.apps.coe.pal.pal.method.constant;
public interface MethodSchemaConst {
String SCHEMA_CATEGORY = "Schema.addCategory(*?);\r\n";
String SCHEMA_GLOBAL_COMMAND = "Schema.addGlobalCommand(*?);\r\n";
String SCHEMA_SHAPE = "Schema.addShape(*?);\r\n";
}

View File

@ -59,4 +59,7 @@ public interface PALMethodConst {
* flowchart的AppId
*/
public final static String APP_PROCESS_FLOWCHART = "com.actionsoft.apps.coe.method.process.flowchart";
String ATTR_FILE_DC_REPOSITORY_NAME = "attr_upfile";
}

View File

@ -0,0 +1,297 @@
package com.actionsoft.apps.coe.pal.pal.method.model;
import java.io.Serializable;
import com.actionsoft.apps.coe.pal.pal.method.util.PALMethodSchemaUtil;
import com.actionsoft.i18n.I18nRes;
/**
* 建模方法基础信息model
*/
public class PALBasicMethodModel implements Serializable {
/**
* methodId 全局唯一标识
*/
private String id;
/**
* 所属资产库Id
*/
private String wsId;
/**
* 建模方法Id
*/
private String methodId;
/**
* 建模方法标题
*/
private String title;
/**
* 建模方法标题-英文
*/
private String titleEn;
/**
* 建模方法标题-繁体
*/
private String titleBig5;
/**
* 建模方法描述
*/
private String desc;
/**
* 建模方法描述-英文
*/
private String descEn;
/**
* 建模方法描述-繁体
*/
private String descBig5;
/**
* 建模方法所属的建模分类,多个之间用逗号分割
*/
private String category;
/**
* 所属appId
*/
private String appId;
/**
* 是否文件夹类型建模方法
*/
private boolean isFolder;
/**
* 当前建模方法的分类
*/
private String methodType;
/**
* 建模方法图标
*/
private String iconCode;
/**
* 建模方法图标颜色
*/
private String iconColor;
/**
* 支持的建模方式多个则逗号分隔
*/
private String modelingMode;
/**
* 默认的建模方式
*/
private String defaultModelingMode;
/**
* 建模方法类型normal普通建模方法image图片库类型建模方法
*/
private String type;
/**
* 形状排序
*/
private String shapeSort;
/**
* 是否为自定义建模方法
*/
private boolean isCustom;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getWsId() {
return wsId;
}
public void setWsId(String wsId) {
this.wsId = wsId;
}
public String getMethodId() {
return methodId;
}
public void setMethodId(String methodId) {
this.methodId = methodId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitleEn() {
return titleEn;
}
public void setTitleEn(String titleEn) {
this.titleEn = titleEn;
}
public String getTitleBig5() {
return titleBig5;
}
public void setTitleBig5(String titleBig5) {
this.titleBig5 = titleBig5;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getDescEn() {
return descEn;
}
public void setDescEn(String descEn) {
this.descEn = descEn;
}
public String getDescBig5() {
return descBig5;
}
public void setDescBig5(String descBig5) {
this.descBig5 = descBig5;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public boolean isFolder() {
return isFolder;
}
public void setFolder(boolean folder) {
isFolder = folder;
}
public String getMethodType() {
return methodType;
}
public void setMethodType(String methodType) {
this.methodType = methodType;
}
public String getIconCode() {
return iconCode;
}
public void setIconCode(String iconCode) {
this.iconCode = iconCode;
}
public String getIconColor() {
return iconColor;
}
public void setIconColor(String iconColor) {
this.iconColor = iconColor;
}
public String getModelingMode() {
return modelingMode;
}
public void setModelingMode(String modelingMode) {
this.modelingMode = modelingMode;
}
public String getDefaultModelingMode() {
return defaultModelingMode;
}
public void setDefaultModelingMode(String defaultModelingMode) {
this.defaultModelingMode = defaultModelingMode;
}
public String getSchema() {
return PALMethodSchemaUtil.getSchema(id, wsId);
}
public String getCustomSchema() {
return "";
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getShapeSort() {
return shapeSort;
}
public void setShapeSort(String shapeSort) {
this.shapeSort = shapeSort;
}
public boolean isCustom() {
return isCustom;
}
public void setCustom(boolean custom) {
isCustom = custom;
}
/**
* title 多语言数据 标识建模方法名称
*/
public String getTitleI18N() {
String lang = I18nRes.getUserLanguage();
if ("cn".equals(lang)) {
return title;
} else if ("en".equals(lang)) {
return titleEn;
} else if ("big5".equals(lang)) {
return titleBig5;
}
return desc;
}
/**
* desc 多语言数据
*/
public String getDescI18N() {
String lang = I18nRes.getUserLanguage();
if ("cn".equals(lang)) {
return desc;
} else if ("en".equals(lang)) {
return descEn;
} else if ("big5".equals(lang)) {
return descBig5;
}
return desc;
}
@Override
public String toString() {
return "PALBasicMethodModel{" + "id='" + id + '\'' + ", wsId='" + wsId + '\'' + ", methodId='" + methodId + '\'' + ", title='" + title + '\'' + ", titleEn='" + titleEn + '\'' + ", titleBig5='" + titleBig5 + '\'' + ", desc='" + desc + '\'' + ", descEn='" + descEn + '\'' + ", descBig5='" + descBig5 + '\'' + ", category='" + category + '\'' + ", appId='" + appId + '\'' + ", isFolder=" + isFolder + ", methodType='" + methodType + '\'' + ", iconCode='" + iconCode + '\'' + ", iconColor='" + iconColor + '\'' + ", modelingMode='" + modelingMode + '\''
+ ", defaultModelingMode='" + defaultModelingMode + '\'' + ", type='" + type + '\'' + ", shapeSort='" + shapeSort + '\'' + ", isCustom=" + isCustom + '}';
}
}

View File

@ -33,6 +33,7 @@ public final class PALMethodAttributeModel implements Cloneable {
//新增两个属性desc和isRequired
private String desc;
private boolean isRequired;
private int index;// 用于排序
/**
* 该定义由哪个App提供
@ -237,4 +238,14 @@ public final class PALMethodAttributeModel implements Cloneable {
}
return null;
}
/**
* 用于排序
*/
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}

View File

@ -0,0 +1,108 @@
package com.actionsoft.apps.coe.pal.pal.method.model;
import java.io.Serializable;
import com.actionsoft.i18n.I18nRes;
import com.alibaba.fastjson.JSONObject;
/**
* 图元分组实体类
*/
public class PALMethodCategorySchemaModel implements Serializable {
/**
* 全局唯一标识36位
**/
private String id;
/**
* category标识
*/
private String key;
/**
* 分组标题-中文
*/
private String text;
/**
* 分组标题-英文
*/
private String textEn;
/**
* 分组标题-繁体
*/
private String textBig5;
/**
* category内容
*/
private JSONObject content;
public PALMethodCategorySchemaModel() {
}
/**
* Getter And Setter
*/
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getTextEn() {
return textEn;
}
public void setTextEn(String textEn) {
this.textEn = textEn;
}
public String getTextBig5() {
return textBig5;
}
public void setTextBig5(String textBig5) {
this.textBig5 = textBig5;
}
public JSONObject getContent() {
return content;
}
public void setContent(JSONObject content) {
this.content = content;
}
public String getTextI18N() {
String lang = I18nRes.getUserLanguage();
if ("cn".equals(lang)) {
return text;
} else if ("en".equals(lang)) {
return textEn;
} else if ("big5".equals(lang)) {
return textBig5;
}
return text;
}
}

View File

@ -0,0 +1,49 @@
package com.actionsoft.apps.coe.pal.pal.method.model;
import java.io.Serializable;
public class PALMethodFunctionSchemaModel implements Serializable {
/**
* 全局唯一标识36位
*/
private String id;
/**
* shape标识
*/
private String key;
/**
* shape内容
*/
private String content;
public PALMethodFunctionSchemaModel() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}

View File

@ -0,0 +1,54 @@
package com.actionsoft.apps.coe.pal.pal.method.model;
import java.io.Serializable;
import com.alibaba.fastjson.JSONArray;
/**
* canvas片段引用实体类
*/
public class PALMethodGlobalCommandSchemaModel implements Serializable {
/**
* 全局唯一标识36位
*/
private String id;
/**
* globalCommand标识
*/
private String key;
/**
* globalCommand内容
*/
private JSONArray content;
public PALMethodGlobalCommandSchemaModel() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public JSONArray getContent() {
return content;
}
public void setContent(JSONArray content) {
this.content = content;
}
}

View File

@ -0,0 +1,142 @@
package com.actionsoft.apps.coe.pal.pal.method.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import com.actionsoft.apps.coe.pal.pal.method.util.PALMethodSchemaUtil;
/**
* 形状定义schema
*
* @author sunlianhui
*/
public final class PALMethodSchemaModel implements Serializable {
private String id;// 全局唯一标识
private String methodId;// 建模方法标识
private String wsId;// 资产库Id
private String appId;// 哪个App提供的
private String lang;// 语言标识
private Long lastModified;// xml最后修改日期用于scanner扫描更新
private String schema;// 形状定义
private String customSchema;// 自定义形状定义
private List<PALMethodCategorySchemaModel> categorySchemaList;// 图元分组List
private List<PALMethodGlobalCommandSchemaModel> globalCommandSchemaList;// canvas片段引用List
private List<PALMethodShapeSchemaModel> shapeSchemaList;// 形状定义List
private List<PALMethodFunctionSchemaModel> functionSchemaList;// 函数定义List
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMethodId() {
return methodId;
}
public void setMethodId(String methodId) {
this.methodId = methodId;
}
public String getWsId() {
return wsId;
}
public void setWsId(String wsId) {
this.wsId = wsId;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getLang() {
return lang;
}
public void setLang(String lang) {
this.lang = lang;
}
public Long getLastModified() {
return lastModified;
}
public void setLastModified(Long lastModified) {
this.lastModified = lastModified;
}
public String getSchema() {
return PALMethodSchemaUtil.getSchema(methodId, wsId);
}
public void setSchema(String schema) {
this.schema = schema;
}
public String getCustomSchema() {
return customSchema;
}
public void setCustomSchema(String customSchema) {
this.customSchema = customSchema;
}
public List<PALMethodCategorySchemaModel> getCategorySchemaList() {
if (CollectionUtils.isEmpty(categorySchemaList)) {
return new ArrayList<>();
}
return categorySchemaList;
}
public void setCategorySchemaList(List<PALMethodCategorySchemaModel> categorySchemaList) {
this.categorySchemaList = categorySchemaList;
}
public List<PALMethodGlobalCommandSchemaModel> getGlobalCommandSchemaList() {
if (CollectionUtils.isEmpty(globalCommandSchemaList)) {
return new ArrayList<>();
}
return globalCommandSchemaList;
}
public void setGlobalCommandSchemaList(List<PALMethodGlobalCommandSchemaModel> globalCommandSchemaList) {
this.globalCommandSchemaList = globalCommandSchemaList;
}
public List<PALMethodShapeSchemaModel> getShapeSchemaList() {
if (CollectionUtils.isEmpty(shapeSchemaList)) {
return new ArrayList<>();
}
return shapeSchemaList;
}
public void setShapeSchemaList(List<PALMethodShapeSchemaModel> shapeSchemaList) {
this.shapeSchemaList = shapeSchemaList;
}
public List<PALMethodFunctionSchemaModel> getFunctionSchemaList() {
if (CollectionUtils.isEmpty(functionSchemaList)) {
return new ArrayList<>();
}
return functionSchemaList;
}
public void setFunctionSchemaList(List<PALMethodFunctionSchemaModel> functionSchemaList) {
this.functionSchemaList = functionSchemaList;
}
@Override
public String toString() {
return "PALMethodSchemaModel{" + "id='" + id + '\'' + ", methodId='" + methodId + '\'' + ", appId='" + appId + '\'' + ", lang='" + lang + '\'' + ", lastModified=" + lastModified + ", schema='" + schema + '\'' + ", customSchema='" + customSchema + '\'' + '}';
}
}

View File

@ -0,0 +1,184 @@
package com.actionsoft.apps.coe.pal.pal.method.model;
import java.io.Serializable;
import com.actionsoft.i18n.I18nRes;
import com.alibaba.fastjson.JSONObject;
/**
* 形状定义实体类
*/
public class PALMethodShapeSchemaModel implements Serializable {
/**
* 全局位置标识36位
*/
private String id;
/**
* shape标识
*/
private String key;
/**
* 样式分类colorOverlay:颜色叠加noColorOverlay:没有颜色叠加
*/
private String styleType;
/**
* 是否出厂自带的形状
*/
private boolean isDefault;
/**
* 形状类型image:全部是图片类型canvas:canvas画出来或canvas+图标类型
*/
private String shapeType;
/**
* 是否允许出现复制
*/
private boolean allowOccurrence;
/**
* 是否启用
*/
private boolean isAvailable;
/**
* 标题-中文
*/
private String title;
/**
* 标题-英文
*/
private String titleEn;
/**
* 标题-繁体
*/
private String titleBig5;
/**
* 是否为自定义图元
*/
private boolean isCustomSchema;
/**
* shape内容
*/
private JSONObject content;
public PALMethodShapeSchemaModel() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getStyleType() {
return styleType;
}
public void setStyleType(String styleType) {
this.styleType = styleType;
}
public boolean isDefault() {
return isDefault;
}
public void setDefault(boolean aDefault) {
isDefault = aDefault;
}
public String getShapeType() {
return shapeType;
}
public void setShapeType(String shapeType) {
this.shapeType = shapeType;
}
public boolean isAllowOccurrence() {
return allowOccurrence;
}
public void setAllowOccurrence(boolean allowOccurrence) {
this.allowOccurrence = allowOccurrence;
}
public boolean isAvailable() {
return isAvailable;
}
public void setAvailable(boolean available) {
isAvailable = available;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitleEn() {
return titleEn;
}
public void setTitleEn(String titleEn) {
this.titleEn = titleEn;
}
public String getTitleBig5() {
return titleBig5;
}
public void setTitleBig5(String titleBig5) {
this.titleBig5 = titleBig5;
}
public boolean isCustomSchema() {
return isCustomSchema;
}
public void setCustomSchema(boolean customSchema) {
isCustomSchema = customSchema;
}
public JSONObject getContent() {
return content;
}
public void setContent(JSONObject content) {
this.content = content;
}
public String getTitleI18N() {
String lang = I18nRes.getUserLanguage();
if ("cn".equals(lang)) {
return title;
} else if ("en".equals(lang)) {
return titleEn;
} else if ("big5".equals(lang)) {
return titleBig5;
}
return title;
}
}

View File

@ -0,0 +1,888 @@
package com.actionsoft.apps.coe.pal.pal.method.util;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.actionsoft.apps.coe.pal.pal.method.cache.PALBasicMethodCache;
import com.actionsoft.apps.coe.pal.pal.method.cache.PALMethodSchemaCache;
import com.actionsoft.apps.coe.pal.pal.method.constant.MethodSchemaConst;
import com.actionsoft.apps.coe.pal.pal.method.model.PALBasicMethodModel;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodCategorySchemaModel;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodFunctionSchemaModel;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodGlobalCommandSchemaModel;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodSchemaModel;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodShapeSchemaModel;
import com.actionsoft.apps.coe.pal.pal.repository.designer.image.util.CoeDesignerImageUtil;
import com.actionsoft.bpms.server.conf.portal.AWSPortalConf;
import com.actionsoft.i18n.I18nRes;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class PALMethodSchemaUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(PALMethodSchemaUtil.class);
public static String getSchema(String methodId, String wsId) {
PALBasicMethodModel basicModel = PALBasicMethodCache.getModelByMethodIdAndWsId(methodId, wsId);
PALMethodSchemaModel schemaModel = PALMethodSchemaCache.getModelListByMethodIdAndLangAndWsId(methodId, I18nRes.getUserLanguage(), wsId);
if (schemaModel == null || basicModel == null) {
return "";
}
StringBuilder schemaBuilder = new StringBuilder();
// 拼接图元分组
List<PALMethodCategorySchemaModel> categorySchemaList = schemaModel.getCategorySchemaList();
if (CollectionUtils.isNotEmpty(categorySchemaList)) {
for (PALMethodCategorySchemaModel categorySchema : categorySchemaList) {
JSONObject content = categorySchema.getContent();
String contentStr = content.toJSONString();
if (StringUtils.isEmpty(contentStr)) {
continue;
}
String replace = MethodSchemaConst.SCHEMA_CATEGORY.replace("*?", contentStr);
schemaBuilder.append(replace);
}
}
// 拼接function
List<PALMethodFunctionSchemaModel> functionSchemaList = schemaModel.getFunctionSchemaList();
if (CollectionUtils.isNotEmpty(functionSchemaList)) {
for (PALMethodFunctionSchemaModel functionSchemaModel : functionSchemaList) {
String content = functionSchemaModel.getContent();
if (StringUtils.isEmpty(content)) {
continue;
}
schemaBuilder.append(content);
schemaBuilder.append("\r\n");
}
}
// 拼接canvas引用片段
List<PALMethodGlobalCommandSchemaModel> globalCommandSchemaList = schemaModel.getGlobalCommandSchemaList();
if (CollectionUtils.isNotEmpty(globalCommandSchemaList)) {
for (PALMethodGlobalCommandSchemaModel globalCommandSchemaModel : globalCommandSchemaList) {
String key = globalCommandSchemaModel.getKey();
JSONArray content = globalCommandSchemaModel.getContent();
if (content == null || content.isEmpty() || StringUtils.isEmpty(key)) {
continue;
}
String contentStr = content.toJSONString();
String replace = MethodSchemaConst.SCHEMA_GLOBAL_COMMAND.replace("*?", "\"" + key + "\", " + contentStr);
schemaBuilder.append(replace);
}
}
// 拼接形状定义
String shapeSort = basicModel.getShapeSort();
if (shapeSort == null) {
shapeSort = "";
}
List<String> shapeSortList = new ArrayList<>(Arrays.asList(shapeSort.split(",")));
Map<String, Integer> schemaMap = new HashMap<>();
List<PALMethodShapeSchemaModel> shapeSchemaList = schemaModel.getShapeSchemaList();
if (CollectionUtils.isNotEmpty(shapeSchemaList)) {
for (PALMethodShapeSchemaModel shapeSchemaModel : shapeSchemaList) {
// 禁用则跳过
if (!shapeSchemaModel.isAvailable()) {
continue;
}
JSONObject content = shapeSchemaModel.getContent();
if (content == null || content.isEmpty()) {
continue;
}
String png = "../apps/" + schemaModel.getAppId() + "/img/method/" + methodId + "/icon/" + shapeSchemaModel.getKey() + ".png";
String schemaPng = "";
// 是否使用canvas
boolean isCanvasDraw = false;
// 临时转换png为base64
try {
File file = new File(AWSPortalConf.getLocation() + png.substring(3));
if (!shapeSchemaModel.isCustomSchema() && file.exists()) {
// schemaPng = png;
schemaPng = CoeDesignerImageUtil.convertCommonImageToBase64(file);
} else {
isCanvasDraw = true;
}
} catch (IOException e) {
LOGGER.error("图片转base64失败路径{}", png, e);
}
content.put("schemaPng", schemaPng);
content.put("isCanvasDraw", isCanvasDraw);
String contentStr = content.toJSONString();
String replace = MethodSchemaConst.SCHEMA_SHAPE.replace("*?", contentStr);
schemaMap.put(replace, shapeSortList.indexOf(shapeSchemaModel.getKey()));
}
// 将Map转换为List并排序
List<String> sortedKeys = schemaMap.entrySet().stream().sorted(Map.Entry.comparingByValue()).map(Map.Entry::getKey).collect(Collectors.toList());
schemaBuilder.append(String.join("", sortedKeys));
}
return schemaBuilder.toString();
}
//
// /**
// * 获取形状Map
// *
// * @param wsId 资产库Id
// * @param methodId 建模方法Id
// * @param shapes map
// */
// public static void getShapesMap(String wsId, String methodId, Map<String, String> shapes) {
// String lang = I18nRes.getUserLanguage();
// PALMethodSchemaModel schemaModel = PALMethodSchemaCache.getModelListByMethodIdAndLangAndWsId(methodId, lang, wsId);
// if (schemaModel == null) {
// return;
// }
// List<PALMethodShapeSchemaModel> shapeSchemaList = schemaModel.getShapeSchemaList();
// for (PALMethodShapeSchemaModel shapeSchemaModel : shapeSchemaList) {
// String name = shapeSchemaModel.getKey();
// shapes.put(name, shapeSchemaModel.getTitleI18N());
// }
// }
//
// /**
// * 更新形状定义缓存
// * 通过给定的建模方法ID和原始的形状定义更新针对所有语言的模式缓存
// *
// * @param methodId 建模方法ID
// * @param originalSchema schema定义
// */
// public static void updateSchemaCache(String methodId, String originalSchema, String wsId) {
// PALBasicMethodModel basicModel = PALBasicMethodCache.getModelByMethodIdAndWsId(methodId, wsId);
// if (basicModel != null) {
// String appId = basicModel.getAppId();
// List<LanguageModel> languageModels = AWSPortalConf.getLanguages();
// for (LanguageModel languageModel : languageModels) {
// String lang = languageModel.getName();
// String schema = transformSchemaByLanguage(appId, originalSchema, lang);
// PALMethodSchemaCache.getModelListByMethodIdAndLangAndWsId(methodId, lang, wsId).setSchema(schema);
// }
// }
// }
//
// /**
// * 更新自定义的形状定义缓存
// * 通过给定的建模方法ID和原始的自定义形状定义更新针对所有语言的模式缓存
// *
// * @param methodId 建模方法ID
// * @param originalSchema 自定义schema定义
// */
// public static void updateCustomSchemaCache(String methodId, String originalSchema, String wsId) {
// PALBasicMethodModel basicModel = PALBasicMethodCache.getModelByMethodIdAndWsId(methodId, wsId);
// if (basicModel != null) {
// String appId = basicModel.getAppId();
// List<LanguageModel> languageModels = AWSPortalConf.getLanguages();
// for (LanguageModel languageModel : languageModels) {
// String lang = languageModel.getName();
// String customSchema = transformSchemaByLanguage(appId, originalSchema, lang);
// PALMethodSchemaCache.getModelListByMethodIdAndLangAndWsId(methodId, lang, wsId).setCustomSchema(customSchema);
// }
// }
// }
//
// /**
// * 更新指定应用下指定建模方法的自定义形状定义缓存
// *
// * @param app AppContext对象
// * @param methodId 建模方法ID
// * @param fileName 自定义形状定义文件名称
// * 该方法通过建模方法ID和文件名从应用的建模方法中加载自定义形状定义内容然后更新对应的自定义形状定义缓存
// */
// public static void updateCustomSchemaCache(AppContext app, String methodId, String fileName, String wsId, boolean isCustom) {
// String customSchema = MethodAppManager.loadCustomSchemaByApp(app, methodId, fileName, wsId, isCustom);
// updateCustomSchemaCache(methodId, customSchema, wsId);
// }
//
// /**
// * 更新指定应用下指定建模方法的形状定义缓存
// *
// * @param app AppContext对象
// * @param methodId 建模方法ID
// * @param fileName 形状定义文件名称
// * 该方法通过建模方法ID和文件名从应用的建模方法中加载形状定义内容然后更新对应的形状定义缓存
// */
// public static void updateSchemaCache(AppContext app, String methodId, String fileName, String wsId, boolean isCustom) {
// String schema = MethodAppManager.loadSchemaByApp(app, methodId, fileName, wsId, isCustom);
// updateSchemaCache(methodId, schema, wsId);
// }
//
// /**
// * 根据指定语言翻译形状定义信息
// *
// * @param app AppContext对象
// * @param originalSchema 原始形状定义信息
// * @param lang 目标语言代码指定要将词汇翻译成的语言例如cnenbig5
// * @return 转换后的模式字符串其中的关键词被翻译成指定语言
// */
// public static String transformSchemaByLanguage(AppContext app, String originalSchema, String lang) {
// return transformSchemaByLanguage(app.getId(), originalSchema, lang);
// }
//
// /**
// * 根据指定语言翻译形状定义信息
// *
// * @param appId 应用ID
// * @param originalSchema 原始形状定义信息
// * @param lang 目标语言代码指定要将词汇翻译成的语言例如cnenbig5
// * @return 转换后的模式字符串其中的关键词被翻译成指定语言
// */
// public static String transformSchemaByLanguage(String appId, String originalSchema, String lang) {
// Map<String, Map<String, String>> map = I18nRes.getResourceMapByApp(appId);
// // 对map的键进行排序确保更长的键先被处理并且只包含中文字符的键被加入
// Map<String, Map<String, String>> sortedMap = new TreeMap<>(Comparator.comparingInt(String::length).reversed() // 首先根据字符串长度排序
// .thenComparing(Comparator.naturalOrder())); // 长度相同则根据字符串的自然顺序排序
//
// // 正则表达式用于检测字符串中是否包含中文字符不含中文字符会造成后续判断误伤
// String chineseCharactersPattern = "[\u4e00-\u9fa5]";
//
// // 过滤并放入sortedMap
// for (Map.Entry<String, Map<String, String>> entry : map.entrySet()) {
// if (entry.getKey().matches(".*" + chineseCharactersPattern + ".*")) {
// sortedMap.put(entry.getKey(), entry.getValue());
// }
// }
//
// StringBuilder result = new StringBuilder();
// int start = 0;
//
// // 遍历替换
// for (int i = 0; i < originalSchema.length(); i++) {
// if (originalSchema.charAt(i) == '"') { // 检测到双引号寻找下一个双引号以确定完整的词汇
// int nextQuote = originalSchema.indexOf('"', i + 1);
// if (nextQuote > i) {
// String completeWord = originalSchema.substring(i, nextQuote + 1); // 包括双引号的完整词汇
// for (String key : sortedMap.keySet()) {
// // 如果找到匹配的完整词汇
// if (completeWord.contains("\"" + key + "\"")) {
// String replacement = sortedMap.get(key).containsKey(lang) ? sortedMap.get(key).get(lang) : sortedMap.get(key).get("cn");
// completeWord = completeWord.replace("\"" + key + "\"", "\"" + replacement + "\"");
// }
// }
// result.append(originalSchema, start, i).append(completeWord); // 添加替换后的完整词汇
// i = nextQuote; // 跳到下一个双引号之后
// start = i + 1;
// }
// }
// }
// if (start < originalSchema.length()) {
// result.append(originalSchema.substring(start)); // 添加剩余部分
// }
// return result.toString();
// }
//
// private static JSONObject transformContentByLanguage(String methodId, Element element, String content, String lang, String elementType) {
// return transformContentByLanguage(methodId, element, content, lang, elementType, "", "");
// }
//
// /**
// * 根据指定语言翻译形状定义信息
// *
// * @param element xml中需要国际化的标签元素
// * @param content 原始形状定义信息
// * @param lang 目标语言代码指定要将词汇翻译成的语言例如cnenbig5
// * @param elementType 标签元素类型category:图元分组shape:形状定义
// * @param drawIcon shape中drawIcon函数
// * @param onCreated shape中onCreated函数
// * @return 转换后的模式jsonObject对象
// */
// private static JSONObject transformContentByLanguage(String methodId, Element element, String content, String lang, String elementType, String drawIcon, String onCreated) {
// if (StringUtils.isEmpty(content)) {
// return new JSONObject();
// }
// String type = "";
// String replace = "";
//
// if ("category".equals(elementType)) {
// type = "text";
// } else if ("shape".equals(elementType)) {
// type = "title";
// }
//
// if ("cn".equals(lang)) {
// replace = element.attributeValue(type);
// } else if ("en".equals(lang)) {
// replace = element.attributeValue(type + "-en");
// } else if ("big5".equals(lang)) {
// replace = element.attributeValue(type + "-big5");
// }
// JSONObject contentObj;
// try {
// // 替换所有换行以及前后空格
// content = content.replaceAll("\\s*\\n\\s*", "");
// contentObj = JSONObject.parseObject(content);
// if ("category".equals(elementType)) {
// // 替换text
// contentObj.put("text", replace);
// } else if ("shape".equals(elementType)) {
// if (UtilString.isNotEmpty(replace)) {
// contentObj.put("title", replace);
// }
// }
// if (StringUtils.isNotEmpty(drawIcon)) {
// contentObj.put("drawIcon", drawIcon);
// }
// if (StringUtils.isNotEmpty(onCreated)) {
// contentObj.put("onCreated", onCreated);
// }
// } catch (JSONException e) {
// LOGGER.error("[methodId={}, key={}]String transform to JSONObject error:{}", methodId, element.attributeValue("key"), content, e);
// return new JSONObject();
// }
//
// return contentObj;
// }
//
// /**
// * 加载默认的例如基础形状泳池泳道这类公共的形状定义
// *
// * @param methodId 建模方法ID
// * @param fileName tpl文件名称
// */
// public static void loadDefaultSchemaCache(String methodId, String fileName) {
// String path = AppsAPIManager.getInstance().getAppContext(CoEConstant.APP_ID).getPath() + PALMethodConst.DIR_ROOT_CONFIG + fileName;
// Document xmlDocument = XMLUtil.readXML(path);
// if (xmlDocument != null) {
// List<LanguageModel> languageModels = AWSPortalConf.getLanguages();
// for (LanguageModel languageModel : languageModels) {
// String lang = languageModel.getName();
// PALMethodSchemaModel psmm = new PALMethodSchemaModel();
// psmm.setId(PALMethodUtil.getMethodSchemaModelId("default", CoEConstant.APP_ID, methodId, lang));
// psmm.setMethodId(methodId);
// psmm.setAppId(CoEConstant.APP_ID);
// psmm.setLang(lang);
// psmm.setWsId("default");
// //psmm.setSchema(PALMethodSchemaUtil.transformSchemaByLanguage(CoEConstant.APP_ID, basicTpl, lang));
// buildSchemaConfig(CoEConstant.APP_ID, methodId, psmm, xmlDocument, lang, null);
// // 放入缓存
// PALMethodSchemaCache.putModel(psmm);
// }
// }
// }
//
// /**
// * 初始化 diagram.schema.xml 文件
// */
// public static void initSchemaXml(DCContext configDc, String wsId, String methodId, PALBasicMethodModel basicModel) {
// DCContext dcContext = configDc.clone();
// dcContext.setFileName(MethodConfigEnum.SCHEMA_CONFIG.getFile());
// Document document = DocumentHelper.createDocument();
// Element schema = document.addElement("schema");
// Element categories = schema.addElement("categories");
// Element category = categories.addElement("category");
// String categoryStr = handleMethodToCategory(methodId);
// category.addAttribute("key", categoryStr);
// category.addAttribute("text", basicModel.getTitle());
// category.addAttribute("text-en", basicModel.getTitleEn());
// category.addAttribute("text-big5", basicModel.getTitleBig5());
// JSONObject jo = new JSONObject();
// jo.put("name", categoryStr);
// jo.put("text", basicModel.getTitle());
// jo.put("dataAttributes", new JSONArray());
// category.setText(jo.toJSONString());
// // 新增三个空标签
// schema.addElement("functions");
// schema.addElement("globalCommands");
// schema.addElement("shapes");
//
// XMLUtil.writeXml(document, dcContext);
//
// // 缓存重新加载
// PALMethodSchemaUtil.reloadCache(CoEConstant.APP_ID, wsId, methodId, document, null);
// }
//
// /**
// * 建模方法转category
// */
// public static String handleMethodToCategory(String methodId) {
// if (methodId == null) {
// return null;
// }
// return methodId.replace("_", "-").replace(".", "_");
// }
//
// /**
// * 构建schema配置
// * 该方法通过解析XML文档构建出图元分类函数全局命令和形状定义等配置信息并填充到PALMethodSchemaModel对象中
// *
// * @param appId AppId
// * @param psmm PAL方法模式模型用于接收构建好的schema配置信息
// * @param schemaDocument schema文档包含待解析的XML文档
// * @param lang 语言代码指定解析时使用的语言
// * @param schemaKeys 图元key集合用于判断是否为自定义图元
// */
// public static void buildSchemaConfig(String appId, String methodId, PALMethodSchemaModel psmm, Document schemaDocument, String lang, Set<String> schemaKeys) {
// try {
// Element rootElement = schemaDocument.getRootElement();
//
// // 构建图元分类
// List<PALMethodCategorySchemaModel> categoryList = buildSchemaList(methodId, rootElement, MethodSchemaEnum.SCHEMA_CATEGORY, PALMethodCategorySchemaModel.class, appId, lang);
// psmm.setCategorySchemaList(categoryList);
//
// // 构建function
// List<PALMethodFunctionSchemaModel> functionList = buildSchemaList(methodId, rootElement, MethodSchemaEnum.SCHEMA_FUNCTION, PALMethodFunctionSchemaModel.class, appId, lang);
// psmm.setFunctionSchemaList(functionList);
//
// // 构建canvas片段引用
// List<PALMethodGlobalCommandSchemaModel> globalCommandList = buildSchemaList(methodId, rootElement, MethodSchemaEnum.SCHEMA_GLOBAL_COMMAND, PALMethodGlobalCommandSchemaModel.class, appId, lang);
// psmm.setGlobalCommandSchemaList(globalCommandList);
//
// // 构建形状定义
// List<PALMethodShapeSchemaModel> shapeList = buildSchemaList(methodId, rootElement, MethodSchemaEnum.SCHEMA_SHAPE, PALMethodShapeSchemaModel.class, appId, lang, schemaKeys);
// psmm.setShapeSchemaList(shapeList);
//
// } catch (Exception e) {
// LOGGER.error(e.getMessage(), e);
// }
// }
//
// /**
// * 重新加载 图元缓存数据
// */
// public static void reloadCache(String appId, String wsId, String methodId, Document document, Set<String> schemaKeys) {
// // 缓存更新
// PALMethodSchemaCache.removeByMethodIdAndWsId(methodId, wsId);
// List<LanguageModel> languageModels = AWSPortalConf.getLanguages();
// for (LanguageModel languageModel : languageModels) {
// String lang = languageModel.getName();
// PALMethodSchemaModel psmm = new PALMethodSchemaModel();
// psmm.setId(PALMethodUtil.getMethodSchemaModelId(wsId, appId, methodId, lang));
// psmm.setAppId(appId);
// psmm.setMethodId(methodId);
// psmm.setWsId(wsId);
// psmm.setLang(lang);
// PALMethodSchemaUtil.buildSchemaConfig(appId, methodId, psmm, document, lang, schemaKeys);
// // 放入缓存
// PALMethodSchemaCache.putModel(psmm);
// }
// }
//
// /**
// * 根据给定的XML根元素构建并返回一个模型列表
// *
// * @param rootElement XML文档的根元素
// * @param schemaEnum 指定的模式枚举用于确定要解析的XML子元素
// * @param modelClass 模型类的Class对象用于实例化模型对象
// * @param appId 应用Id
// * @param lang 国际化参数
// * @return 返回一个包含解析和实例化后模型对象的列表
// */
// private static <T> List<T> buildSchemaList(String methodId, Element rootElement, MethodSchemaEnum schemaEnum, Class<T> modelClass, String appId, String lang) {
// return buildSchemaList(methodId, rootElement, schemaEnum, modelClass, appId, lang, null);
// }
//
// /**
// * 根据给定的XML根元素构建并返回一个模型列表
// *
// * @param rootElement XML文档的根元素
// * @param schemaEnum 指定的模式枚举用于确定要解析的XML子元素
// * @param modelClass 模型类的Class对象用于实例化模型对象
// * @param appId 应用Id
// * @param lang 国际化参数
// * @param schemaKeys 图元key集合用于判断是否为自定义图元
// * @return 返回一个包含解析和实例化后模型对象的列表
// */
// private static <T> List<T> buildSchemaList(String methodId, Element rootElement, MethodSchemaEnum schemaEnum, Class<T> modelClass, String appId, String lang, Set<String> schemaKeys) {
// List<T> modelList = new ArrayList<>();
// Element schemaElement = rootElement.element(schemaEnum.getTagGroupName());
// if (schemaElement != null) {
// List<Element> elements = schemaElement.elements(schemaEnum.getTagName());
// for (Element element : elements) {
// T model;
// try {
// // 实例化
// model = modelClass.getDeclaredConstructor().newInstance();
// // 设置公共部分
// model.getClass().getMethod("setId", String.class).invoke(model, UUIDGener.getUUID());
// model.getClass().getMethod("setKey", String.class).invoke(model, element.attributeValue("key"));
//
// // 设置PALMethodCategorySchemaModel独有部分
// Method textMethod = CoEReflectionUtils.findMethod(model.getClass(), "setText", String.class);
// if (textMethod != null && StringUtils.isNotEmpty(element.attributeValue("text"))) {
// textMethod.invoke(model, element.attributeValue("text"));
// }
// Method textEnMethod = CoEReflectionUtils.findMethod(model.getClass(), "setTextEn", String.class);
// if (textEnMethod != null && StringUtils.isNotEmpty(element.attributeValue("text-en"))) {
// textEnMethod.invoke(model, element.attributeValue("text-en"));
// }
// Method textBig5Method = CoEReflectionUtils.findMethod(model.getClass(), "setTextBig5", String.class);
// if (textBig5Method != null && StringUtils.isNotEmpty(element.attributeValue("text-big5"))) {
// textBig5Method.invoke(model, element.attributeValue("text-big5"));
// }
//
// // 设置PALMethodShapeSchemaModel独有部分
// Method styleTypeMethod = CoEReflectionUtils.findMethod(model.getClass(), "setStyleType", String.class);
// if (styleTypeMethod != null && StringUtils.isNotEmpty(element.attributeValue("styleType"))) {
// styleTypeMethod.invoke(model, element.attributeValue("styleType"));
// }
// Method defaultMethod = CoEReflectionUtils.findMethod(model.getClass(), "setDefault", boolean.class);
// if (defaultMethod != null && StringUtils.isNotEmpty(element.attributeValue("isDefault"))) {
// defaultMethod.invoke(model, Boolean.valueOf(element.attributeValue("isDefault")));
// }
// Method shapeTypeMethod = CoEReflectionUtils.findMethod(model.getClass(), "setShapeType", String.class);
// if (shapeTypeMethod != null && StringUtils.isNotEmpty(element.attributeValue("shapeType"))) {
// shapeTypeMethod.invoke(model, element.attributeValue("shapeType"));
// }
// Method allowOccurenceMethod = CoEReflectionUtils.findMethod(model.getClass(), "setAllowOccurrence", boolean.class);
// if (allowOccurenceMethod != null && StringUtils.isNotEmpty(element.attributeValue("allowOccurrence"))) {
// allowOccurenceMethod.invoke(model, Boolean.valueOf(element.attributeValue("allowOccurrence")));
// }
// Method availableMethod = CoEReflectionUtils.findMethod(model.getClass(), "setAvailable", boolean.class);
// if (availableMethod != null && StringUtils.isNotEmpty(element.attributeValue("isAvailable"))) {
// availableMethod.invoke(model, Boolean.valueOf(element.attributeValue("isAvailable")));
// }
// Method titleMethod = CoEReflectionUtils.findMethod(model.getClass(), "setTitle", String.class);
// if (titleMethod != null && StringUtils.isNotEmpty(element.attributeValue("title"))) {
// titleMethod.invoke(model, element.attributeValue("title"));
// }
// Method titleEnMethod = CoEReflectionUtils.findMethod(model.getClass(), "setTitleEn", String.class);
// if (titleEnMethod != null && StringUtils.isNotEmpty(element.attributeValue("title-en"))) {
// titleEnMethod.invoke(model, element.attributeValue("title-en"));
// }
// Method titleBig5Method = CoEReflectionUtils.findMethod(model.getClass(), "setTitleBig5", String.class);
// if (titleBig5Method != null && StringUtils.isNotEmpty(element.attributeValue("title-big5"))) {
// titleBig5Method.invoke(model, element.attributeValue("title-big5"));
// }
// if (schemaKeys != null) {
// Method customSchemaMethod = CoEReflectionUtils.findMethod(model.getClass(), "setCustomSchema", boolean.class);
// if (customSchemaMethod != null) {
// customSchemaMethod.invoke(model, schemaKeys.contains(element.attributeValue("key")));
// }
// }
//
// // 设置content部分
// String content = element.getText();
// String drawIcon = "";
// String onCreated = "";
// Element drawIconElement = element.element("drawIcon");
// if (drawIconElement != null) {
// drawIcon = drawIconElement.getText();
// }
// Element onCreatedElement = element.element("onCreated");
// if (onCreatedElement != null) {
// onCreated = onCreatedElement.getText();
// }
// if (schemaEnum.name().equals(MethodSchemaEnum.SCHEMA_FUNCTION.name())) {
// model.getClass().getMethod("setContent", String.class).invoke(model, content);
// } else if (schemaEnum.name().equals(MethodSchemaEnum.SCHEMA_CATEGORY.name())) {
// // 对图元分组content进行国际化处理
// JSONObject contentObj = transformContentByLanguage(methodId, element, content, lang, "category");
// model.getClass().getMethod("setContent", JSONObject.class).invoke(model, contentObj);
// } else if (schemaEnum.name().equals(MethodSchemaEnum.SCHEMA_SHAPE.name())) {
// // 对形状定义进行国际化处理
// JSONObject contentObj = transformContentByLanguage(methodId, element, content, lang, "shape", drawIcon, onCreated);
// // 放入建模方法Id
// contentObj.put("methodId", methodId);
// model.getClass().getMethod("setContent", JSONObject.class).invoke(model, contentObj);
// } else if (schemaEnum.name().equals(MethodSchemaEnum.SCHEMA_GLOBAL_COMMAND.name())) {
// try {
// model.getClass().getMethod("setContent", JSONArray.class).invoke(model, JSONArray.parseArray(content));
// } catch (JSONException e) {
// LOGGER.error("[method={}, key={}]String transform to JSONArray error:{}", methodId, element.attributeValue("key"), content, e);
// }
// }
// modelList.add(model);
// } catch (Exception e) {
// // 适当的异常处理逻辑
// LOGGER.error(e.getMessage(), e);
// }
// }
// }
// return modelList;
// }
//
// /**
// * 返回对应图元id的 model数据
// */
// public static PALMethodShapeSchemaModel getShapeSchemaBySchemaId(String wsId, String methodId, String lang, String schemaId) {
// PALMethodSchemaModel schemaModel = PALMethodSchemaCache.getModelListByMethodIdAndLangAndWsId(methodId, lang, wsId);
// if (schemaModel != null) {
// return schemaModel.getShapeSchemaList().stream().filter(item -> item.getKey().equals(schemaId)).findFirst().orElse(null);
// }
// return null;
// }
//
// /**
// * 获取 默认 globalCommand 数据
// */
// public static JSONObject getDefaultGlobalCommand() {
// JSONObject jo = new JSONObject();
// String rectangle = "[{\n" + " action: \"move\",\n" + " x: \"0\",\n" + " y: \"0\"\n" + "},\n" + " {\n" + " action: \"line\",\n" + " x: \"w\",\n" + " y: \"0\"\n" + " },\n" + " {\n" + " action: \"line\",\n" + " x: \"w\",\n" + " y: \"h\"\n" + " },\n" + " {\n" + " action: \"line\",\n" + " x: \"0\",\n" + " y: \"h\"\n" + " },\n" + " {\n" + " action: \"close\"\n" + " }]";
// jo.put("rectangle", JSONArray.parseArray(rectangle));
// String round = "[{\n" + " action: \"move\",\n" + " x: \"0\",\n" + " y: \"h/2\"\n" + "},\n" + " {\n" + " action: \"curve\",\n" + " x1: \"0\",\n" + " y1: \"-h/6\",\n" + " x2: \"w\",\n" + " y2: \"-h/6\",\n" + " x: \"w\",\n" + " y: \"h/2\"\n" + " },\n" + " {\n" + " action: \"curve\",\n" + " x1: \"w\",\n" + " y1: \"h+h/6\",\n" + " x2: \"0\",\n" + " y2: \"h+h/6\",\n" + " x: \"0\",\n" + " y: \"h/2\"\n" + " },\n" + " {\n" + " action: \"close\"\n" + " }]";
// jo.put("round", JSONArray.parseArray(round));
// String roundRectangle =
// "[{\n" + " action: \"move\",\n" + " x: \"0\",\n" + " y: \"4\"\n" + "},\n" + " {\n" + " action: \"quadraticCurve\",\n" + " x1: \"0\",\n" + " y1: \"0\",\n" + " x: \"4\",\n" + " y: \"0\"\n" + " },\n" + " {\n" + " action: \"line\",\n" + " x: \"w-4\",\n" + " y: \"0\"\n" + " },\n" + " {\n" + " action: \"quadraticCurve\",\n" + " x1: \"w\",\n" + " y1: \"0\",\n" + " x: \"w\",\n" + " y: \"4\"\n" + " },\n" + " {\n" + " action: \"line\",\n" + " x: \"w\",\n" + " y: \"h-4\"\n" + " },\n" + " {\n" + " action: \"quadraticCurve\",\n" + " x1: \"w\",\n"
// + " y1: \"h\",\n" + " x: \"w-4\",\n" + " y: \"h\"\n" + " },\n" + " {\n" + " action: \"line\",\n" + " x: \"4\",\n" + " y: \"h\"\n" + " },\n" + " {\n" + " action: \"quadraticCurve\",\n" + " x1: \"0\",\n" + " y1: \"h\",\n" + " x: \"0\",\n" + " y: \"h-4\"\n" + " },\n" + " {\n" + " action: \"close\"\n" + " }]";
// jo.put("roundRectangle", JSONArray.parseArray(roundRectangle));
// return jo;
// }
//
// /**
// * 获取图元中 图片的 base64 数据
// *
// * @param wsId 资产库id
// * @param methodId 建模方法
// * @param schemaTypeEnum 图元类型枚举
// * @param isCustom 是否自定义
// * @param schemaDataModel 图元数据model
// */
// public static JSONObject getImageBase64InSchemaData(String wsId, String methodId, PalSchemaTypeEnum schemaTypeEnum, boolean isCustom, PalSchemaDataModel schemaDataModel) {
// String iconFileName = "";
// JSONObject jo = new JSONObject();
// String imageId = null;
// String oldImagePath = null;
// JSONArray pathJa = schemaDataModel.getPath();
// if (pathJa != null) {
// for (int i = 0; i < pathJa.size(); i++) {
// JSONObject pathJo = pathJa.getJSONObject(i);
// if (schemaTypeEnum == PalSchemaTypeEnum.CANVAS) {
// if (pathJo.containsKey("iconImage")) {
// JSONObject iconImage = pathJo.getJSONObject("iconImage");
// imageId = iconImage.getString("imageId");
// iconFileName = iconImage.getString("iconFileName");
// break;
// }
// }
// if (schemaTypeEnum == PalSchemaTypeEnum.IMAGE) {
// if (pathJo.containsKey("fillStyle")) {
// JSONObject fillStyle = pathJo.getJSONObject("fillStyle");
// String type = fillStyle.getString("type");
// String fileId = fillStyle.getString("fileId");
// iconFileName = fillStyle.getString("iconFileName");
// if ("imageDef".equals(type) && fileId != null) {
// imageId = fileId;
// break;
// }
// if ("image".equals(type) && fileId != null) {
// oldImagePath = fileId;
// break;
// }
// }
// }
// }
// }
// jo.put("base64", "");
// jo.put("iconFileName", iconFileName);
// if (imageId != null) {
// DCContext imageFileDc = PALWorkSpaceMethodConfigUtil.getMethodConfigDc(wsId, methodId, imageId, isCustom);
// jo.put("imageFilePath", imageFileDc.getFilePath());
// jo.put("base64", CoeDcUtil.dcContextToString(imageFileDc));
// }
// if (oldImagePath != null) {
// // ../apps开头默认为web下目录替换路径
// if (oldImagePath.indexOf("../apps") == 0) {
// oldImagePath = AWSPortalConf.getLocation() + oldImagePath.substring(3);
// }
// File imageFile = new File(oldImagePath.replaceAll("\\.svg$", ".png"));
// try {
// String base64 = CoeDesignerImageUtil.convertCommonImageToBase64(imageFile);
// jo.put("imageFilePath", imageFile.getAbsolutePath());
// jo.put("base64", base64);
// jo.put("iconFileName", imageFile.getName());
// } catch (IOException e) {
// LOGGER.error("文件转换base64失败文件路径{}", imageFile.getPath(), e);
// throw new AWSException("文件转换base64失败");
// }
// }
// return jo;
// }
//
// /**
// * 获取iconColor
// */
// public static String getIconColor(JSONArray iconJa) {
// String iconColor = "51,51,51";
// for (int i = 0; i < iconJa.size(); i++) {
// JSONObject iconJo = iconJa.getJSONObject(i);
// JSONObject lineStyle = iconJo.getJSONObject("lineStyle");
// JSONObject fillStyle = iconJo.getJSONObject("fillStyle");
// if (lineStyle != null) {
// String lineColor = lineStyle.getString("lineColor");
// if (lineColor != null) {
// iconColor = lineColor;
// }
// }
// if (fillStyle != null) {
// String fillColor = fillStyle.getString("color");
// if (fillColor != null) {
// iconColor = fillColor;
// }
// }
// }
// return iconColor;
// }
//
// /**
// * 获取形状是否允许出现复制
// *
// * @param wsId 资产库Id
// * @param methodId 建模方法Id
// * @param shapeName 形状name
// * @return 是否允许出现复制
// */
// public static boolean getSchemaShapeAllowOccurrence(String wsId, String methodId, String shapeName) {
// PALMethodSchemaModel schemaModel = PALMethodSchemaCache.getModelListByMethodIdAndLangAndWsId(methodId, I18nRes.getUserLanguage(), wsId);
// if (schemaModel == null) {
// return false;
// }
// List<PALMethodShapeSchemaModel> shapeSchemaList = schemaModel.getShapeSchemaList();
// for (PALMethodShapeSchemaModel shapeSchema : shapeSchemaList) {
// if (shapeSchema.getKey().equals(shapeName)) {
// return shapeSchema.isAllowOccurrence();
// }
// }
// return false;
// }
//
// /**
// * 获取当前资产库下所有形状定义文件里面的functions定义
// *
// * @param wsId 资产库ID
// * @return 当前资产库下所有形状定义文件里面的functions定义
// */
// public static JSONObject getMethodFunctions(String wsId) {
// List<PALMethodModel> methodList = new ArrayList<>();
// List<String> categories = PALMethodCache.getPALMethodList(true, wsId);
// for (String category : categories) {
// methodList.addAll(PALMethodCache.getPALMethodModelListByMethod(category, wsId));
// }
// // 单独处理泳池泳道和基本形状
// PALMethodModel lane = PALMethodCache.getPALMethodModelById("lane", wsId);
// if (lane != null) {
// methodList.add(lane);
// }
// PALMethodModel basic = PALMethodCache.getPALMethodModelById("basic", wsId);
// if (basic != null) {
// methodList.add(basic);
// }
// List<String> methodIds = methodList.stream().map(PALMethodModel::getMethodId).collect(Collectors.toList());
// // 获取所有的functions
// return getMethodIdsFunctions(wsId, methodIds);
// }
//
// /**
// * 获取当前资产库下建模方法的functions定义
// *
// * @param wsId 资产库ID
// * @param methodIds 建模方法ID集合
// * @return 获取当前资产库下建模方法的functions定义
// */
// public static JSONObject getMethodIdsFunctions(String wsId, List<String> methodIds) {
// JSONObject functionObj = new JSONObject();
// // 获取所有的functions
// for (String methodId : methodIds) {
// PALMethodSchemaModel schemaModel = PALMethodSchemaCache.getModelListByMethodIdAndLangAndWsId(methodId, I18nRes.getUserLanguage(), wsId);
// if (schemaModel == null) {
// continue;
// }
// // 拼接function
// List<PALMethodFunctionSchemaModel> functionSchemaList = schemaModel.getFunctionSchemaList();
// if (CollectionUtils.isNotEmpty(functionSchemaList)) {
// for (PALMethodFunctionSchemaModel functionSchemaModel : functionSchemaList) {
// String content = functionSchemaModel.getContent();
// String key = functionSchemaModel.getKey();
// if (StringUtils.isEmpty(content)) {
// continue;
// }
// content = content.trim();
// // 使用正则表达式提取函数名称
// String functionName = extractFunctionName(key);
// // 转换函数声明格式
// content = transformFunctionDeclaration(content, functionName);
// functionObj.put(functionName, content);
// }
// }
// }
// return functionObj;
// }
//
// /**
// * 转换函数声明格式
// */
// public static String transformFunctionDeclaration(String content, String functionName) {
// // 检查输入是否为空或不以"function"开头
// if (UtilString.isEmpty(content) || UtilString.isEmpty(functionName) || !content.trim().startsWith("function")) {
// return content;
// }
// // 替换函数名称
// return content.replaceFirst("^\\s*function\\s+" + functionName, "function");
// }
//
// /**
// * 使用正则表达式提取函数名称
// */
// private static String extractFunctionName(String key) {
// String regex = "^(\\w+)\\(";
// Pattern pattern = Pattern.compile(regex);
// Matcher matcher = pattern.matcher(key);
// if (matcher.find()) {
// return matcher.group(1);
// }
// return "";
// }
//
// /**
// * 获取图元数据
// */
// public static String getSchemaByMethodIds(boolean isAdmin, String wsId, String methodId, List<String> methodIds) {
// StringBuilder shapes = new StringBuilder();
// PALMethodModel mModel = PALMethodCache.getPALMethodModelByMethodIdAndWsId(methodId, wsId);
//
// // 是否允许用户自定义模板0不允许1允许
// String isCustomDefine = SDK.getAppAPI().getProperty(CoEConstant.APP_ID, CoEConstant.PROPERTY_CUSTOM_DEFINE_SCHEMA);
//
// if (mModel != null) {
// String schema = mModel.getSchema();
// shapes.append(schema).append("\r\n");
// }
// for (String cate : methodIds) {
// if ("basic".equals(cate)) {
// shapes.append(PALMethodCache.getBasicTpl(wsId)).append("\r\n");
// continue;
// }
// if ("lane".equals(cate)) {
// String laneTpl = PALMethodCache.getLaneTpl(wsId);
// shapes.append(laneTpl).append("\r\n");
// continue;
// }
// PALMethodModel methodModel = PALMethodCache.getPALMethodModelByMethodIdAndWsId(cate, wsId);
// if (methodModel == null) {
// continue;
// }
// String schema = methodModel.getSchema();
// if ("0".equals(isCustomDefine)) {
// shapes.append(schema).append("\r\n");
// } else {
// if (isAdmin) {
// shapes.append(schema).append("\r\n");
// } else {
// shapes.append(MethodSchemaConst.SCHEMA_SHAPE.replace("*?", schema)).append("\r\n");
// }
// shapes.append(methodModel.getCustomSchema()).append("\r\n");
// }
// }
// return shapes.toString();
// }
//
// /**
// * 获取图元数据 根据建模方法ID
// */
// public static String getSchemaByMethodId(String wsId, String methodId) {
// PALMethodModel model = PALMethodCache.getPALMethodModelByMethodIdAndWsId(methodId, wsId);
// if (model == null) {
// return "";
// }
// return model.getSchema();
// }
}

View File

@ -14,6 +14,8 @@ import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodModel;
import com.actionsoft.apps.coe.pal.system.logger.CoeLogger;
import com.actionsoft.apps.coe.pal.system.property.CoePropertyUtil;
import com.actionsoft.i18n.I18nRes;
import com.actionsoft.apps.coe.pal.pal.method.model.PALBasicMethodModel;
import com.actionsoft.apps.coe.pal.pal.method.cache.PALBasicMethodCache;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@ -286,4 +288,32 @@ public class PALMethodUtil {
// System.out.println(getShapeDialog("process.epc","basic"));
}
/**
* 获取建模方法的图标
*
* @param methodId
* @return
*/
public static JSONObject getPALMethodIconById(String methodId, String wsId) {
String code = "";
String color = "";
if ("default".equals(methodId)) {// 默认文件夹
code = "&#xe621;";
color = "#FFB718";
} else {
PALBasicMethodModel model = PALBasicMethodCache.getModelByMethodIdAndWsId(methodId, wsId);
if (model == null) {
code = "&#xe621;";
color = "#FFB718";
} else {
code = model.getIconCode();
color = model.getIconColor();
}
}
JSONObject result = new JSONObject();
result.put("code", code);
result.put("color", color);
return result;
}
}

View File

@ -0,0 +1,68 @@
package com.actionsoft.apps.coe.pal.pal.processexec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.actionsoft.apps.coe.pal.pal.processexec.constant.B2PControlModeEnum;
import com.actionsoft.apps.coe.pal.pal.processexec.constant.P2BControlModeEnum;
import com.actionsoft.apps.coe.pal.pal.repository.cache.CoeProcessLevelCorrelateCache;
import com.actionsoft.apps.coe.pal.pal.repository.model.CoeProcessLevelCorrelateModel;
/**
* @author oYang
* @Description 梳理到执行关联管理 业务逻辑处理
* @createTime 2024年09月10日 14:34:00
*/
public class ProcessExecAPIManager {
private static final Logger log = LoggerFactory.getLogger(ProcessExecAPIManager.class);
private ProcessExecAPIManager() {
}
public static ProcessExecAPIManager getInstance() {
return SingletonHolder.INSTANCE;
}
/**
* 梳理到执行 流程层面 判断是否有控制权限根据应用参数判定
*
* @param plId PAL端流程ID
* @return boolean
*/
public boolean hasProcessControlPerm(String plId) {
return hasProcessControlPerm(plId, true);
}
private static class SingletonHolder {
private static final ProcessExecAPIManager INSTANCE = new ProcessExecAPIManager();
}
/**
* 梳理到执行 流程层面 判断是否有控制权限根据应用参数判定
*
* @param plId PAL端流程ID
* @return boolean
*/
public boolean hasProcessControlPerm(String plId, boolean isPal) {
boolean hasPerm = true;
CoeProcessLevelCorrelateModel correlateModel = CoeProcessLevelCorrelateCache.getCache().get(plId);
if (correlateModel != null) {
int correlateType = correlateModel.getCorrelateType();
int controlMode = correlateModel.getControlMode();
if (correlateType == 1) {
P2BControlModeEnum controlModeEnum = P2BControlModeEnum.getByValue(controlMode);
if (controlModeEnum != null) {
return isPal ? controlModeEnum.getPalProcessHasPerm() : controlModeEnum.getBpmProcessHasPerm();
}
} else {
B2PControlModeEnum controlModeEnum = B2PControlModeEnum.getByValue(controlMode);
if (controlModeEnum != null) {
return isPal ? controlModeEnum.getPalProcessHasPerm() : controlModeEnum.getBpmProcessHasPerm();
}
}
}
return hasPerm;
}
}

View File

@ -0,0 +1,85 @@
package com.actionsoft.apps.coe.pal.pal.processexec.constant;
/**
* @author oYang
* @Description BPM推送PAL 流程控制模式
* @createTime 2024年09月20日 15:15:00
*/
public enum B2PControlModeEnum {
/**
* 以PAL为中心+BPM图结构只读
*/
PAL_BPM_READ_ONLY(1, "以PAL为中心+BPM图结构只读", false, false, true, true),
/**
* 以PAL为中心+BPM图可编辑
*/
PAL_BPM_EDIT(2, "以PAL为中心+BPM图可编辑", false, true, true, true),
/**
* 以BPM为中心+PAL图结构只读
*/
BPM_PAL_READ_ONLY(3, "以BPM为中心+PAL图结构只读", true, true, false, false),
/**
* 以BPM为中心+PAL图结构可编辑
*/
BPM_PAL_EDIT(4, "以BPM为中心+PAL图结构可编辑", true, true, false, true),
/**
* 不限制
*/
NONE(5, "不限制", true, true, true, true);
private final Integer value;
private final String desc;
private final Boolean bpmProcessHasPerm; // BPM流程层面控制权限
private final Boolean bpmProcessDiagramHasPerm; // BPM流程图结构控制权限
private final Boolean palProcessHasPerm; // PAL流程层面控制权限
private final Boolean palProcessDiagramHasPerm; // PAL流程图结构控制权限
B2PControlModeEnum(Integer value, String desc, Boolean bpmProcessHasPerm, Boolean bpmProcessDiagramHasPerm, Boolean palProcessHasPerm, Boolean palProcessDiagramHasPerm) {
this.value = value;
this.desc = desc;
this.bpmProcessHasPerm = bpmProcessHasPerm;
this.bpmProcessDiagramHasPerm = bpmProcessDiagramHasPerm;
this.palProcessHasPerm = palProcessHasPerm;
this.palProcessDiagramHasPerm = palProcessDiagramHasPerm;
}
public static B2PControlModeEnum getByValue(Integer value) {
for (B2PControlModeEnum mode : values()) {
if (mode.getValue().equals(value)) {
return mode;
}
}
return null;
}
public Integer getValue() {
return value;
}
public String getDesc() {
return desc;
}
public Boolean getBpmProcessHasPerm() {
return bpmProcessHasPerm;
}
public Boolean getBpmProcessDiagramHasPerm() {
return bpmProcessDiagramHasPerm;
}
public Boolean getPalProcessHasPerm() {
return palProcessHasPerm;
}
public Boolean getPalProcessDiagramHasPerm() {
return palProcessDiagramHasPerm;
}
}

View File

@ -0,0 +1,83 @@
package com.actionsoft.apps.coe.pal.pal.processexec.constant;
/**
* @author oYang
* @Description PAL端推送BPM端的流程控制模式
* @createTime 2024年09月20日 14:55:00
*/
public enum P2BControlModeEnum {
/**
* 以PAL为中心+BPM图结构只读
*/
PAL_BPM_READ_ONLY(1, "以PAL为中心+BPM图结构只读", false, false, true, true),
/**
* 以PAL为中心+BPM图可编辑
*/
PAL_BPM_EDIT(2, "以PAL为中心+BPM图可编辑", false, true, true, true),
/**
* 以BPM为中心+PAL图结构只读
*/
BPM_PAL_READ_ONLY(3, "以BPM为中心+PAL图结构只读", true, true, false, false),
/**
* 以BPM为中心+PAL图结构可编辑
*/
BPM_PAL_EDIT(4, "以BPM为中心+PAL图结构可编辑", true, true, false, true),
/**
* 不限制
*/
NONE(5, "不限制", true, true, true, true);
private final Integer value;
private final String desc;
private final Boolean bpmProcessHasPerm; // BPM流程层面控制权限
private final Boolean bpmProcessDiagramHasPerm; // BPM流程图结构控制权限
private final Boolean palProcessHasPerm; // PAL流程层面控制权限
private final Boolean palProcessDiagramHasPerm; // PAL流程图结构控制权限
P2BControlModeEnum(Integer value, String desc, Boolean bpmProcessHasPerm, Boolean bpmProcessDiagramHasPerm, Boolean palProcessHasPerm, Boolean palProcessDiagramHasPerm) {
this.value = value;
this.desc = desc;
this.bpmProcessHasPerm = bpmProcessHasPerm;
this.bpmProcessDiagramHasPerm = bpmProcessDiagramHasPerm;
this.palProcessHasPerm = palProcessHasPerm;
this.palProcessDiagramHasPerm = palProcessDiagramHasPerm;
}
public static P2BControlModeEnum getByValue(Integer value) {
for (P2BControlModeEnum mode : values()) {
if (mode.getValue().equals(value)) {
return mode;
}
}
return null;
}
public Integer getValue() {
return value;
}
public String getDesc() {
return desc;
}
public Boolean getBpmProcessHasPerm() {
return bpmProcessHasPerm;
}
public Boolean getBpmProcessDiagramHasPerm() {
return bpmProcessDiagramHasPerm;
}
public Boolean getPalProcessHasPerm() {
return palProcessHasPerm;
}
public Boolean getPalProcessDiagramHasPerm() {
return palProcessDiagramHasPerm;
}
}

View File

@ -2,6 +2,8 @@ package com.actionsoft.apps.coe.pal.pal.repository.designer;
import java.io.File;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import com.actionsoft.apps.coe.pal.pal.manage.util.PalManageUtil;
import com.actionsoft.bpms.bpmn.engine.cache.ProcessDefCache;
@ -1431,5 +1433,15 @@ public class CoeDesignerShapeAPIManager {
}
return jsVal;
}
/**
* 获取所有已排序的有效且使用中的形状属性
*
* @param wsId 资产库ID
* @param methodId 建模方法ID
* @return key attrKey value PALMethodAttributeModel
*/
public Map<String, PALMethodAttributeModel> getAllValidAndUseShapeAttributeModelsMap(String wsId, String methodId) {
return getAllValidAndUseShapeAttributeModels(wsId, methodId).stream().collect(Collectors.toMap(PALMethodAttributeModel::getKey, Function.identity()));
}
}

View File

@ -96,5 +96,9 @@ public class CoeDesignerConstant {
public final static int ADAPTER_DESGINER_PROCESS = 1;
public final static int REALTIME_LISTEN_TIME = 30;
/**
* 版本对比页面
*/
public final static String DESIGNER_VERSION_COMPARE_PAGE = "pal.pl.repository.designer.graph.versionCompare.htm";
}

View File

@ -0,0 +1,59 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.constant;
/**
* @author oYang
* @Description 节点变化类型连线只有新增
* @createTime 2024年08月07日 11:47:00
*/
public enum DiffNodeTypeEnum {
/**
* 新增
*/
ADD("add", "新增"),
/**
* 删除
*/
DELETE("delete", "删除"),
/**
* 位置
*/
POSITION("position", "位置"),
/**
* 信息
*/
INFO("info", "信息"),
/**
* 样式
*/
STYLE("style", "样式");
private final String code;
private final String desc;
DiffNodeTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static DiffNodeTypeEnum getByCode(String code) {
for (DiffNodeTypeEnum type : DiffNodeTypeEnum.values()) {
if (type.getCode().equals(code)) {
return type;
}
}
return null;
}
public String getCode() {
return code;
}
public String getDesc() {
return desc;
}
}

View File

@ -0,0 +1,52 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.constant;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import com.actionsoft.bpms.util.UtilString;
/**
* @author oYang
* @Description 版本状态枚举
* @createTime 2024年07月29日 14:51:00
*/
public enum VersionStatusEnum {
USE("use", "设计中"), PUBLISH("publish", "已发布"), STOP("stop", "已停用"), APPROVAL("approval", "审核中"), DESIGNER("designer", "设计");
private static final Map<String, VersionStatusEnum> codeToStatus = new HashMap<>();
static {
for (VersionStatusEnum status : VersionStatusEnum.values()) {
codeToStatus.put(status.code, status);
}
}
String code;
String desc;
VersionStatusEnum(String code, String desc) {
if (UtilString.isEmpty(code) || UtilString.isEmpty(desc)) {
throw new IllegalArgumentException("Code and Desc must not be null");
}
this.code = code;
this.desc = desc;
}
public static Optional<VersionStatusEnum> getByCode(String code) {
if (UtilString.isEmpty(code)) {
throw new IllegalArgumentException("Code must not be null");
}
VersionStatusEnum status = codeToStatus.get(code);
return Optional.ofNullable(status);
}
public String getCode() {
return code;
}
public String getDesc() {
return desc;
}
}

View File

@ -0,0 +1,56 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.dto;
/**
* @author oYang
* @Description 版本对比参数
* @createTime 2024年08月02日 11:43:00
*/
public class VersionCompareDTO {
private String wsId;
private String teamId;
private String compareVerId;
private String curId;
public VersionCompareDTO() {
}
public VersionCompareDTO(String wsId, String teamId, String compareVerId, String curId) {
this.wsId = wsId;
this.teamId = teamId;
this.compareVerId = compareVerId;
this.curId = curId;
}
public String getWsId() {
return wsId;
}
public void setWsId(String wsId) {
this.wsId = wsId;
}
public String getTeamId() {
return teamId;
}
public void setTeamId(String teamId) {
this.teamId = teamId;
}
public String getCompareVerId() {
return compareVerId;
}
public void setCompareVerId(String compareVerId) {
this.compareVerId = compareVerId;
}
public String getCurId() {
return curId;
}
public void setCurId(String curId) {
this.curId = curId;
}
}

View File

@ -0,0 +1,46 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.dto;
/**
* @author oYang
* @Description 版本列表
* @createTime 2024年07月29日 11:12:00
*/
public class VersionListDTO {
private String wsId;
private String teamId;
private String id;
public VersionListDTO() {
}
public VersionListDTO(String wsId, String teamId, String id) {
this.wsId = wsId;
this.teamId = teamId;
this.id = id;
}
public String getWsId() {
return wsId;
}
public void setWsId(String wsId) {
this.wsId = wsId;
}
public String getTeamId() {
return teamId;
}
public void setTeamId(String teamId) {
this.teamId = teamId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}

View File

@ -0,0 +1,411 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.image.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.batik.ext.awt.image.codec.imageio.ImageIOJPEGImageWriter;
import org.apache.batik.ext.awt.image.spi.ImageWriterRegistry;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
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.image.dao.CoeUserShapeImageDao;
//import com.actionsoft.apps.coe.pal.pal.repository.designer.image.model.CoeUserShapeImageModel;
//import com.actionsoft.apps.coe.pal.pal.repository.designer.util.CoeDesignerDcUtil;
import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryModel;
import com.actionsoft.apps.coe.pal.util.CoeDcUtil;
import com.actionsoft.apps.resource.plugin.profile.DCPluginProfile;
import com.actionsoft.bpms.server.fs.DCContext;
import com.actionsoft.bpms.server.fs.dc.DCProfileManager;
import com.actionsoft.bpms.server.fs.dc.DCUtil;
import com.actionsoft.bpms.util.UtilFile;
import com.actionsoft.bpms.util.UtilString;
import com.actionsoft.exception.AWSException;
import com.actionsoft.i18n.I18nRes;
import com.actionsoft.sdk.local.SDK;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
/**
* 设计器图片处理工具类
*/
public class CoeDesignerImageUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(CoeDesignerImageUtil.class);
/**
* 图片正则校验
*/
public static final String imgReg = ".*\\.(jpg|jpeg|png|gif|svg|tiff|bmp)$";
// /**
// * 获取前端上传DC的临时目录
// *
// * @param userId 用户id
// */
// public static DCContext getTmpShapeImageDc(String userId) {
// return DCUtil.createTempFileContext(CoEConstant.APP_ID, CoeDesignerConstant.DESIGNER_SHAPE_IMAGES, userId, null);
// }
//
// /**
// * 获取 形状图片数据 名称内容数据 <br/>
// * 即keyimageId, value图片的base64 数据
// *
// * @param wsId 资产库id
// * @param uuid 模型id
// */
// public static JSONObject getImageBase64Jo(String wsId, String uuid) {
// DCContext defineDc = CoeDesignerDcUtil.getDefineDc(wsId, uuid);
// return getImageBase64JoByPlDc(defineDc);
// }
//
// /**
// * 获取 形状图片数据 名称内容数据 <br/>
// * 即keyimageId, value图片的base64 数据
// *
// * @param dcContext 模型文件所在的DC对象
// */
// public static JSONObject getImageBase64JoByPlDc(DCContext dcContext) {
// JSONObject result = new JSONObject();
// if (dcContext == null) {
// return result;
// }
// dcContext.setFileName(CoeDesignerConstant.PL_IMAGE_FILE_NAME);
// if (dcContext.existFile()) {
// JSONArray array = CoeDcUtil.dcContextToJa(dcContext);
// for (int i = 0; i < array.size(); i++) {
// String name = array.getString(i);
// if (name.contains(".")) {
// continue;
// }
// dcContext.setFileName(name);
// String base64 = CoeDcUtil.dcContextToString(dcContext);
// result.put(name, base64);
// }
// }
// return result;
// }
//
// /**
// * 处理 形状图片文件夹 shapeimages
// */
// public static void handleShapeImagesByDefine(JSONObject definition, PALRepositoryModel plModel, boolean isCustom) {
// // 获取形状 json中 形状图片 fileId 内容集合
// List<String> shapeImageList = new ArrayList<>();
// JSONObject elements = definition.getJSONObject("elements");
// for (String key : elements.keySet()) {
// JSONObject shape = elements.getJSONObject(key);
// // 统计形状文件id
// if (shape.containsKey("fillStyle")) {
// JSONObject fillStyle = shape.getJSONObject("fillStyle");
// String fileId = fillStyle.getString("fileId");
// if (fileId != null) {
// shapeImageList.add(fileId);
// }
// }
// if (shape.containsKey("path")) {
// JSONArray pathJa = shape.getJSONArray("path");
// for (int i = 0; i < pathJa.size(); i++) {
// JSONObject path = pathJa.getJSONObject(i);
// if (path.containsKey("fillStyle")) {
// JSONObject fillStyle = path.getJSONObject("fillStyle");
// String fileId = fillStyle.getString("fileId");
// if (fileId != null) {
// shapeImageList.add(fileId);
// }
// }
// if (path.containsKey("iconImage")) {
// JSONObject iconImage = path.getJSONObject("iconImage");
// String imageId = iconImage.getString("imageId");
// if (imageId != null) {
// shapeImageList.add(imageId);
// }
// }
// }
// }
// }
// // 生成并复制图片定义中的图片 并删除冗余文件
// CoeDesignerImageDefUtil.generateAndCopyImageDef(shapeImageList, plModel.getWsId(), plModel.getMethodId(), plModel.getId(), isCustom);
// }
//
// /**
// * 组装 define 数据 fillStyle和path 中添加 base64数据
// */
// public static String wrapperShapeImagesIntoDefine(String define, PALRepositoryModel plModel) {
// JSONObject imageBase64Jo = CoeDesignerImageUtil.getImageBase64Jo(plModel.getWsId(), plModel.getId());
// return wrapperShapeImagesIntoDefine(define, imageBase64Jo);
// }
//
// /**
// * 组装 define 数据 fillStyle和path 中添加 base64数据
// */
// public static String wrapperShapeImagesIntoDefine(String define, JSONObject imageBase64Jo) {
// if (UtilString.isEmpty(define) || imageBase64Jo == null || imageBase64Jo.isEmpty()) {
// return define;
// }
// JSONObject definition = JSONObject.parseObject(define);
// JSONObject elements = definition.getJSONObject("elements");
// for (String key : elements.keySet()) {
// JSONObject shape = elements.getJSONObject(key);
// JSONObject fillStyle = shape.getJSONObject("fillStyle");
// if (fillStyle != null) {
// // 数据为paste的来源
// String fileId = fillStyle.getString("fileId");
// String from = fillStyle.getString("from");
// // 存在 fileId from
// if (fileId != null && from != null) {
// if (imageBase64Jo.containsKey(fileId)) {
// fillStyle.put("base64", imageBase64Jo.getString(fileId));
// } else {
// LOGGER.error("图片生成处理,填充图片错误[错误]图片ID{}", fileId);
// }
// }
// }
// JSONArray pathJa = shape.getJSONArray("path");
// if (pathJa != null) {
// for (int i = 0; i < pathJa.size(); i++) {
// JSONObject path = pathJa.getJSONObject(i);
// JSONObject pathFileStyle = path.getJSONObject("fillStyle");
// if (pathFileStyle != null) {
// String fileId = pathFileStyle.getString("fileId");
// if (fileId != null) {
// if (imageBase64Jo.containsKey(fileId)) {
// pathFileStyle.put("base64", imageBase64Jo.getString(fileId));
// } else {
// LOGGER.error("图片生成处理填充图元icon错误[错误]图片ID{}", fileId);
// }
// }
// }
// }
// }
// }
// return definition.toJSONString();
// }
//
// /**
// * 将base64转换为bytes数据
// *
// * @param base64String 图片image
// * @return base64数据
// */
// public static byte[] convertBase64ToBytes(String base64String) {
// // 组装参数
// try {
// // 去掉"data:image/png;base64,"前缀
// String[] baseSplit = base64String.split(",");
// String base64Data;
// String imageType = "png";
// // 定义正则表达式
// String regex = "data:image\\/([^;]+);base64";
// if (baseSplit.length > 1) {
// // 获取图片类型
// base64Data = baseSplit[1];
// // 编译正则表达式
// Pattern pattern = Pattern.compile(regex);
// // 创建匹配器
// Matcher matcher = pattern.matcher(baseSplit[0]);
// // 使用非贪婪匹配
// if (matcher.find()) {
// imageType = matcher.group(1);
// // 处理svg类型
// if ("svg+xml".equalsIgnoreCase(imageType)) {
// imageType = "svg";
// }
// }
// } else {
// base64Data = baseSplit[0];
// }
// byte[] bytes = Base64.getDecoder().decode(base64Data);
// if ("svg".equals(imageType)) {
// String base64Str = svgBytesToBase64(bytes);
// base64Str = base64Str.replaceAll("\r?\n", "");
// bytes = Base64.getDecoder().decode(base64Str);
// // 存入携带前缀的base64数据
// }
// return bytes;
// } catch (TranscoderException e) {
// throw new AWSException(I18nRes.findValue(CoEConstant.APP_ID, "base64数据存储错误"), e);
// }
// }
//
// /**
// * 将图片转存储为base64 PNG + base64 存储两个文件且删除原文件
// *
// * @param imageFileDc 图片文件
// */
// public static String dumpImageToBase64(DCContext imageFileDc) {
// try {
// String fileName = imageFileDc.getFileName();
// if (!imageFileDc.existFile() || !fileName.contains(".")) {
// return "";
// }
// // 获取无后缀的路径
// int i = fileName.lastIndexOf(".");
// String sFileName = fileName.substring(0, i);
// String base64String;
// if (fileName.endsWith(".svg")) {
// base64String = convertSvgToBase64(imageFileDc);
// } else {
// base64String = convertCommonImageToBase64(imageFileDc);
// }
// if (!fileName.matches(".png$")) {
// // 删除原本文件
// imageFileDc.delete();
// // 将base64转为png存储
// imageFileDc.setFileName(sFileName + ".png");
// SDK.getDCAPI().write(base64StringToInputStream(base64String), imageFileDc);
// }
// // 将base64直接存入文件
// DCContext cloneImageFileDc = imageFileDc.clone();
// cloneImageFileDc.setFileName(sFileName);
// base64String = base64String.replaceAll("\\s", "+");
// CoeDcUtil.write(base64String, cloneImageFileDc);
// return base64String;
// } catch (IOException e) {
// throw new AWSException(I18nRes.findValue(CoEConstant.APP_ID, "图片存储失败"));
// }
// }
/**
* 常规图片转base64
*/
public static String convertCommonImageToBase64(DCContext imageFileDc) throws IOException {
byte[] bytes = CoeDcUtil.dcContextToByte(imageFileDc);
return "data:image/png;base64," + Base64.getEncoder().encodeToString(bytes);
}
/**
* 常规图片转base64
*/
public static String convertCommonImageToBase64(File imageFile) throws IOException {
byte[] imageBytes = Files.readAllBytes(imageFile.toPath());
return "data:image/png;base64," + Base64.getEncoder().encodeToString(imageBytes);
}
// /**
// * 转换svg图片为base64
// */
// private static String convertSvgToBase64(DCContext imageFileDc) {
// byte[] bytes = CoeDcUtil.dcContextToByte(imageFileDc);
// try {
// String base64Str = svgBytesToBase64(bytes);
// base64Str = base64Str.replaceAll("\r?\n", "");
// return "data:image/png;base64," + base64Str;
// } catch (Exception e) {
// throw new AWSException(I18nRes.findValue(CoEConstant.APP_ID, "转换svg文件发生错误"), e);
// }
// }
//
// /**
// * svg 二进制数据 转换为 base64 数据
// */
// private static String svgBytesToBase64(byte[] bytes) throws TranscoderException {
// String decodedSvg = new String(bytes, StandardCharsets.UTF_8);
// if (decodedSvg.contains("href=\"")) {
// String substring = decodedSvg.substring(decodedSvg.indexOf("href=\"") + 6, decodedSvg.lastIndexOf("\""));
// if (substring.split("\\.").length > 1) {
// return substring.split("\\.")[1];
// } else {
// return substring;
// }
// } else if (!decodedSvg.contains("<svg")) {
// return Base64.getEncoder().encodeToString(bytes);
// } else {
// ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
// ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// TranscoderInput input = new TranscoderInput(inputStream);
// TranscoderOutput output = new TranscoderOutput(outputStream);
// JPEGTranscoder transcoder = new JPEGTranscoder();
// // JPEG实现 注册
// ImageWriterRegistry.getInstance().register(new ImageIOJPEGImageWriter());
// transcoder.transcode(input, output);
// byte[] pngBytes = outputStream.toByteArray();
// return Base64.getEncoder().encodeToString(pngBytes);
// }
// }
//
// /**
// * 获取DC shapeimages imageId 路径 <br/>
// * DC/shapeimages/userId/imageId/
// */
// public static DCContext getCommonShapeImageDc(String userId, String imageId, String fileName) {
// DCPluginProfile dcProfile = DCProfileManager.getDCProfile(CoEConstant.APP_ID, CoeDesignerConstant.DESIGNER_SHAPE_IMAGES);
// return new DCContext(null, dcProfile, CoEConstant.APP_ID, userId, imageId, fileName);
// }
//
// /**
// * 依据用户删除文件目录
// */
// public static void deleteDirByUserId(String userId) {
// List<CoeUserShapeImageModel> imageModels = new CoeUserShapeImageDao().queryListByUserId(userId);
// for (CoeUserShapeImageModel imageModel : imageModels) {
// DCContext commonShapeImageDc = getCommonShapeImageDc(userId, imageModel.getImageId(), imageModel.getFileName());
// commonShapeImageDc.delete();
// }
// }
//
// /**
// * 获取图片base64内容并转换为 InputStream 对象
// */
// @Deprecated
// public static InputStream getShapeImagesIS(String filePath) {
// UtilFile file = new UtilFile(filePath);
// if (file.exists()) {
// if (!file.getName().contains(".")) {
// String base64String = file.readStrUTF8();
// String base64Data = base64String.substring(base64String.indexOf(",") + 1);
// base64Data = base64Data.replaceAll("\\s", "+");
// byte[] bytes = Base64.getDecoder().decode(base64Data);
// return new ByteArrayInputStream(bytes);
// }
// }
// return null;
// }
//
// /**
// * 获取图片base64内容并转换为 InputStream 对象
// */
// public static InputStream getShapeImagesIS(String plId, String imageId) {
// PALRepositoryModel plModel = PALRepositoryCache.getCache().get(plId);
// if (plModel != null) {
// DCContext dcContext = CoeDesignerDcUtil.getDefineDc(plModel.getWsId(), plModel.getId());
// dcContext.setFileName(imageId);
// if (dcContext.existFile()) {
// return base64StringToInputStream(CoeDcUtil.dcContextToString(dcContext));
// }
// }
// return null;
// }
//
// /**
// * Base64 编码的字符串转换为 InputStream
// *
// * @param base64String Base64 编码的字符串
// * @return 转换后的 InputStream
// */
// public static InputStream base64StringToInputStream(String base64String) {
// if (UtilString.isEmpty(base64String)) {
// return null;
// }
// // 解码 Base64 字符串为字节数组
// byte[] bytes = Base64.getDecoder().decode(base64String.replace("data:image/png;base64,", ""));
// // 创建 ByteArrayInputStream
// return new ByteArrayInputStream(bytes);
// }
}

View File

@ -0,0 +1,115 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.vo;
import com.alibaba.fastjson.annotation.JSONField;
/**
* @author oYang
* @Description 形状属性VO
* @createTime 2024年08月02日 17:51:00
*/
public class AttrVO {
private final String id; // 属性id
private final String name; // 属性名称
private final Object value; // 属性值
private final String type; // 属性类型
private final Boolean isDiff; // 是否有差异
private final Object compareAccord; // 对比依据
private final Integer orderIndex; // 用于排序
private AttrVO(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.value = builder.value;
this.type = builder.type;
this.isDiff = builder.isDiff;
this.compareAccord = builder.compareAccord;
this.orderIndex = builder.orderIndex;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public Object getValue() {
return value;
}
public String getType() {
return type;
}
public Boolean getIsDiff() {
return isDiff;
}
// @JSONField(serialize = false)
public Object getCompareAccord() {
return compareAccord;
}
@JSONField(serialize = false)
public Integer getOrderIndex() {
return orderIndex;
}
public static final class Builder {
private String id;
private String name;
private Object value;
private String type;
private Boolean isDiff;
private Object compareAccord;
private Integer orderIndex;
private Builder() {
}
public static Builder createBuilder() {
return new Builder();
}
public Builder withId(String id) {
this.id = id;
return this;
}
public Builder withName(String name) {
this.name = name;
return this;
}
public Builder withValue(Object value) {
this.value = value;
return this;
}
public Builder withType(String type) {
this.type = type;
return this;
}
public Builder withIsDiff(Boolean isDiff) {
this.isDiff = isDiff;
return this;
}
public Builder withCompareAccord(Object compareAccord) {
this.compareAccord = compareAccord;
return this;
}
public Builder withOrderIndex(Integer orderIndex) {
this.orderIndex = orderIndex;
return this;
}
public AttrVO build() {
return new AttrVO(this);
}
}
}

View File

@ -0,0 +1,53 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.vo;
import java.util.List;
/**
* @author oYang
* @Description 节点及连线对比
* @createTime 2024年08月07日 13:45:00
*/
public class DiffNodeVO {
private final String id; // 节点id或者连线id
private final List<String> type; // 节点或者连线变化类型多个连线只有新增
private DiffNodeVO(Builder builder) {
this.id = builder.id;
this.type = builder.type;
}
public String getId() {
return id;
}
public List<String> getType() {
return type;
}
public static final class Builder {
private String id;
private List<String> type;
private Builder() {
}
public static Builder create() {
return new Builder();
}
public Builder withId(String id) {
this.id = id;
return this;
}
public Builder withType(List<String> type) {
this.type = type;
return this;
}
public DiffNodeVO build() {
return new DiffNodeVO(this);
}
}
}

View File

@ -0,0 +1,111 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.vo;
/**
* @author oYang
* @Description 形状链接
* @createTime 2024年08月05日 15:08:00
*/
public class ShapeLinkVO {
private final String name;
private final String target;
private final String type;
private final String url;
private final String uuid;
private final String value;
private final String versionId;
public ShapeLinkVO(Builder builder) {
this.name = builder.name;
this.target = builder.target;
this.type = builder.type;
this.url = builder.url;
this.uuid = builder.uuid;
this.value = builder.value;
this.versionId = builder.versionId;
}
public String getName() {
return name;
}
public String getTarget() {
return target;
}
public String getType() {
return type;
}
public String getUrl() {
return url;
}
public String getUuid() {
return uuid;
}
public String getValue() {
return value;
}
public String getVersionId() {
return versionId;
}
public static final class Builder {
private String name;
private String target;
private String type;
private String url;
private String uuid;
private String value;
private String versionId;
private Builder() {
}
public static Builder createBuilder() {
return new Builder();
}
public Builder withName(String name) {
this.name = name;
return this;
}
public Builder withTarget(String target) {
this.target = target;
return this;
}
public Builder withType(String type) {
this.type = type;
return this;
}
public Builder withUrl(String url) {
this.url = url;
return this;
}
public Builder withUuid(String uuid) {
this.uuid = uuid;
return this;
}
public Builder withValue(String value) {
this.value = value;
return this;
}
public Builder withVersionId(String versionId) {
this.versionId = versionId;
return this;
}
public ShapeLinkVO build() {
return new ShapeLinkVO(this);
}
}
}

View File

@ -0,0 +1,75 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.vo;
/**
* @author oYang
* @Description 形状附件
* @createTime 2024年08月05日 11:27:00
*/
public class UpFileVO {
private final String fileId;
private final String fileName;
private final String downloadUrl;
private final Boolean hasSecurity;
private UpFileVO(Builder builder) {
this.fileId = builder.fileId;
this.fileName = builder.fileName;
this.downloadUrl = builder.downloadUrl;
this.hasSecurity = builder.hasSecurity;
}
public String getFileId() {
return fileId;
}
public String getFileName() {
return fileName;
}
public String getDownloadUrl() {
return downloadUrl;
}
public Boolean getHasSecurity() {
return hasSecurity;
}
public static final class Builder {
private String fileId;
private String fileName;
private String downloadUrl;
private Boolean hasSecurity;
private Builder() {
}
public static Builder createBuilder() {
return new Builder();
}
public Builder withFileId(String fileId) {
this.fileId = fileId;
return this;
}
public Builder withFileName(String fileName) {
this.fileName = fileName;
return this;
}
public Builder withDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
return this;
}
public Builder withHasSecurity(Boolean hasSecurity) {
this.hasSecurity = hasSecurity;
return this;
}
public UpFileVO build() {
return new UpFileVO(this);
}
}
}

View File

@ -0,0 +1,150 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.vo;
import java.sql.Timestamp;
/**
* @author oYang
* @Description 版本列表
* @createTime 2024年07月29日 11:47:00
*/
public class VersionListVO {
private final String plId;
private final String versionId;
private final String versionNo;
private final String versionStatus;
private final String createUser;
private final String createTime;
private final String updateUser;
private final String updateTime;
private final Boolean hasCreatePerm; // 是否有创建权限
private final Timestamp correlateTime;
private VersionListVO(VersionListBuilder builder) {
this.plId = builder.plId;
this.versionId = builder.versionId;
this.versionNo = builder.versionNo;
this.versionStatus = builder.versionStatus;
this.createUser = builder.createUser;
this.createTime = builder.createTime;
this.updateUser = builder.updateUser;
this.updateTime = builder.updateTime;
this.hasCreatePerm = builder.hasCreatePerm;
this.correlateTime = builder.correlateTime;
}
public String getPlId() {
return plId;
}
public String getVersionId() {
return versionId;
}
public String getVersionNo() {
return versionNo;
}
public String getVersionStatus() {
return versionStatus;
}
public String getCreateUser() {
return createUser;
}
public String getCreateTime() {
return createTime;
}
public String getUpdateUser() {
return updateUser;
}
public String getUpdateTime() {
return updateTime;
}
public Boolean getHasCreatePerm() {
return hasCreatePerm;
}
public Timestamp getCorrelateTime() {
return correlateTime;
}
public static final class VersionListBuilder {
private String plId;
private String versionId;
private String versionNo;
private String versionStatus;
private String createUser;
private String createTime;
private String updateUser;
private String updateTime;
private Boolean hasCreatePerm;
private Timestamp correlateTime;
private VersionListBuilder() {
}
public static VersionListBuilder createBuilder() {
return new VersionListBuilder();
}
public VersionListBuilder withPlId(String plId) {
this.plId = plId;
return this;
}
public VersionListBuilder withVersionId(String versionId) {
this.versionId = versionId;
return this;
}
public VersionListBuilder withVersionNo(String versionNo) {
this.versionNo = versionNo;
return this;
}
public VersionListBuilder withVersionStatus(String versionStatus) {
this.versionStatus = versionStatus;
return this;
}
public VersionListBuilder withCreateUser(String createUser) {
this.createUser = createUser;
return this;
}
public VersionListBuilder withCreateTime(String createTime) {
this.createTime = createTime;
return this;
}
public VersionListBuilder withUpdateUser(String updateUser) {
this.updateUser = updateUser;
return this;
}
public VersionListBuilder withUpdateTime(String updateTime) {
this.updateTime = updateTime;
return this;
}
public VersionListBuilder withHasCreatePerm(Boolean hasCreatePerm) {
this.hasCreatePerm = hasCreatePerm;
return this;
}
public VersionListBuilder withCorrelateTime(Timestamp correlateTime) {
this.correlateTime = correlateTime;
return this;
}
public VersionListVO build() {
return new VersionListVO(this);
}
}
}

View File

@ -0,0 +1,123 @@
package com.actionsoft.apps.coe.pal.pal.repository.designer.web;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
import com.actionsoft.apps.coe.pal.pal.repository.cache.CoeProcessLevelCorrelateCache;
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.dto.VersionCompareDTO;
import com.actionsoft.apps.coe.pal.pal.repository.designer.dto.VersionListDTO;
import com.actionsoft.apps.coe.pal.pal.repository.designer.util.DesignerVersionUtil;
import com.actionsoft.apps.coe.pal.pal.repository.designer.vo.VersionListVO;
import com.actionsoft.apps.coe.pal.pal.repository.model.CoeProcessLevelCorrelateModel;
import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryModel;
import com.actionsoft.bpms.bpmn.engine.cache.ProcessDefCache;
import com.actionsoft.bpms.bpmn.engine.model.def.ProcessDefinition;
import com.actionsoft.bpms.commons.htmlframework.HtmlPageTemplate;
import com.actionsoft.bpms.commons.mvc.view.ActionWeb;
import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.util.UtilString;
import com.actionsoft.exception.AWSException;
import com.actionsoft.i18n.I18nRes;
import com.alibaba.fastjson.JSONObject;
/**
* 设计器流程版本对比 web层
*/
public class CoeDesignerVersionWeb extends ActionWeb {
private static final Logger LOGGER = LoggerFactory.getLogger(CoeDesignerVersionWeb.class);
private final UserContext uc;
public CoeDesignerVersionWeb(UserContext uc) {
super(uc);
this.uc = uc;
}
/**
* 获取版本列表
*
* @param versionListDTO 版本对比参数
*/
public String getVersionList(VersionListDTO versionListDTO) {
ResponseObject ro = ResponseObject.newOkResponse();
String id = versionListDTO.getId();
List<VersionListVO> versionListVoList = new ArrayList<>();
List<VersionListVO> historyVersionListVoList = new ArrayList<>();
PALRepositoryModel palModel = PALRepositoryCache.getCache().get(id);
if (palModel != null) {
// 维护pal模型Id与bpm平台模型Id映射
Map<String, String> mapOfProcessDefId = new HashMap<>();
List<PALRepositoryModel> plVersionModels = PALRepositoryCache.getByVersionId(palModel.getVersionId());
for (PALRepositoryModel model : plVersionModels) {
CoeProcessLevelCorrelateModel correlateModel = CoeProcessLevelCorrelateCache.getCache().get(model.getId());
if (correlateModel == null) {
continue;
}
String processDefId = correlateModel.isCorrelate() ? correlateModel.getPlAwsId() : correlateModel.getSourceAwsId();
if (UtilString.isEmpty(processDefId)) {
continue;
}
ProcessDefinition processDefinition = ProcessDefCache.getInstance().get(processDefId);
if (processDefinition == null) {
continue;
}
mapOfProcessDefId.put(model.getId(), processDefId);
VersionListVO versionListVo = DesignerVersionUtil.getVersionListVo(model, processDefinition, correlateModel.getCreateDate());
versionListVoList.add(versionListVo);
}
if (!versionListVoList.isEmpty()) {
versionListVoList.sort(Comparator.comparing(VersionListVO::getCorrelateTime).reversed());
// 历史版本
historyVersionListVoList = DesignerVersionUtil.getVersionListVoList(id, mapOfProcessDefId);
} else {
versionListVoList = DesignerVersionUtil.getVersionListVoList(id, mapOfProcessDefId);
}
}
ro.put("versionList", versionListVoList);
ro.put("historyList", historyVersionListVoList);
return ro.toString();
}
/**
* 版本对比
*
* @param versionCompareDTO 版本对比参数
*/
public String designerVersionCompare(VersionCompareDTO versionCompareDTO) {
Map<String, Object> macroLibraries = queryDesignerVersionCompareMap(versionCompareDTO);
return HtmlPageTemplate.merge(CoEConstant.APP_ID, CoeDesignerConstant.DESIGNER_VERSION_COMPARE_PAGE, macroLibraries);
}
/**
* 获取 版本对比 map参数
*
* @param versionCompareDTO 版本对比参数
*/
private Map<String, Object> queryDesignerVersionCompareMap(VersionCompareDTO versionCompareDTO) {
// 获取对比版本的模型数据
PALRepositoryModel plModel = PALRepositoryCache.getCache().get(versionCompareDTO.getCompareVerId());
JSONObject versionData = DesignerVersionUtil.getVersionData(uc, versionCompareDTO.getCompareVerId(), versionCompareDTO.getTeamId());
if (versionData == null) {
throw new AWSException(I18nRes.findValue(CoEConstant.APP_ID, "获取待比对的版本数据失败"));
}
// 获取当前模型数据
JSONObject curData = DesignerVersionUtil.getVersionData(uc, versionCompareDTO.getCurId(), versionCompareDTO.getTeamId());
if (curData == null) {
throw new AWSException(I18nRes.findValue(CoEConstant.APP_ID, "获取当前使用的版本数据失败"));
}
return DesignerVersionUtil.queryDesignerVersionCompareMap(plModel.getWsId(), plModel.getMethodId(), plModel.getName(), versionCompareDTO.getCompareVerId(), versionData, versionCompareDTO.getCurId(), curData, false, false);
}
}

View File

@ -1,5 +1,7 @@
package com.actionsoft.apps.coe.pal.pal.repository.model;
import java.sql.Timestamp;
import com.actionsoft.bpms.commons.mvc.model.ModelBean;
/**
@ -26,6 +28,10 @@ public class CoeProcessLevelCorrelateModel extends ModelBean{
public static final String FIELD_EXT2 = "EXT2";// add by sunlh
public static final String FIELD_EXT3 = "EXT3";// add by sunlh
public static final String FIELD_EXT4 = "EXT4";// add by sunlh
public static final String FIELD_SOURCEAWSID = "SOURCEAWSID"; // 来源AWS流程ID 版本迭代时当前流程是由哪个流程新建版本而来
public static final String FIELD_CREATEDATE = "CREATEDATE";
public static final String FIELD_CONTROLMODE = "CONTROLMODE"; // 流程管控模式
private int controlMode;
private String wsId;
private String plId;
@ -39,6 +45,8 @@ public class CoeProcessLevelCorrelateModel extends ModelBean{
private String ext2 = "";
private String ext3 = "";
private String ext4;
private String sourceAwsId;
private Timestamp createDate;
public CoeProcessLevelCorrelateModel() {
this.wsId = "";
@ -135,5 +143,25 @@ public class CoeProcessLevelCorrelateModel extends ModelBean{
public void setExt4(String ext4) {
this.ext4 = ext4;
}
public String getSourceAwsId() {
return sourceAwsId;
}
public void setSourceAwsId(String sourceAwsId) {
this.sourceAwsId = sourceAwsId;
}
public Timestamp getCreateDate() {
return createDate;
}
public void setCreateDate(Timestamp createDate) {
this.createDate = createDate;
}
public int getControlMode() {
return controlMode;
}
public void setControlMode(int controlMode) {
this.controlMode = controlMode;
}
}

View File

@ -0,0 +1,163 @@
package com.actionsoft.apps.coe.pal.pal.repository.upfile.cache;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
import com.actionsoft.apps.coe.pal.pal.repository.upfile.dao.UpFileDao;
import com.actionsoft.apps.coe.pal.pal.repository.upfile.model.UpfileModel;
import com.actionsoft.apps.resource.plugin.profile.CachePluginProfile;
import com.actionsoft.bpms.commons.cache.Cache;
import com.actionsoft.bpms.commons.cache.CacheManager;
import com.actionsoft.bpms.util.UtilString;
import com.actionsoft.exception.AWSException;
import com.actionsoft.i18n.I18nRes;
import com.actionsoft.sdk.local.SDK;
/**
* 资产文件附件Cache
*/
public class PALUpfileCache extends Cache<String, UpfileModel> {
private static final Logger LOGGER = LoggerFactory.getLogger(PALUpfileCache.class);
public PALUpfileCache(CachePluginProfile profile) {
super(profile);
registeIndex(PALUpfileCacheIndex1.class, new PALUpfileCacheIndex1()); // key pl_uuid
}
public static PALUpfileCache getCache() {
return CacheManager.getCache(PALUpfileCache.class);
}
public static void putModel(UpfileModel model) {
if (model == null) {
String msg = I18nRes.findValue(CoEConstant.APP_ID, "附件") + "model" + I18nRes.findValue(CoEConstant.APP_ID, "不允许为空");
throw new AWSException(msg);
}
getCache().put(model.getUuid(), model);
}
public static void removeById(String uuid) {
if (StringUtils.isEmpty(uuid)) {
throw new AWSException(I18nRes.findValue(CoEConstant.APP_ID, "附件") + "uuid" + I18nRes.findValue(CoEConstant.APP_ID, "不允许为空"));
}
getCache().remove(uuid);
}
public static List<UpfileModel> getByPlUuid(String plUuid) {
List<UpfileModel> upfileModels = iteratorToList(getCache().getByIndex(PALUpfileCacheIndex1.class, plUuid));
if (upfileModels.isEmpty()) {
return Collections.emptyList();
}
upfileModels.sort(new UpfileComparator());// 排序
return upfileModels;
}
/**
* 根据 plId 附件类型 删除缓存数据
*/
public static void removeByPlIdAndType(String plUuid, String type) {
if (plUuid == null || type == null) {
return;
}
Iterator<UpfileModel> iter = getCache().getByIndex(PALUpfileCacheIndex1.class, plUuid);
while (iter.hasNext()) {
UpfileModel next = iter.next();
if (next.getType().equals(type)) {
getCache().remove(next.getUuid());
}
}
}
/**
* 根据 plId 删除缓存数据
*/
public static void removeByPlId(String plUuid) {
if (plUuid == null) {
return;
}
Iterator<UpfileModel> iter = getCache().getByIndex(PALUpfileCacheIndex1.class, plUuid);
while (iter.hasNext()) {
UpfileModel next = iter.next();
getCache().remove(next.getUuid());
}
}
public static List<UpfileModel> getByPlUuidAndType(String plUuid, String type) {
List<UpfileModel> listByPlUuid = getByPlUuid(plUuid);
if (listByPlUuid.isEmpty()) {
return Collections.emptyList();
}
listByPlUuid = listByPlUuid.stream()
// 过滤
.filter(item -> type.equals(item.getType()))
// 排序
.sorted(new UpfileComparator()).collect(Collectors.toList());
return listByPlUuid;
}
public static List<UpfileModel> getByPlUuidAndShapeIds(String plUuid, List<String> shapeIds) {
if (UtilString.isEmpty(plUuid) || shapeIds == null || shapeIds.isEmpty()) {
return Collections.emptyList();
}
List<UpfileModel> listByPlUuid = getByPlUuid(plUuid);
if (listByPlUuid.isEmpty()) {
return Collections.emptyList();
}
listByPlUuid = listByPlUuid.stream()
// 过滤
.filter(item -> shapeIds.contains(item.getShape_uuid()))
// 排序
.sorted(new UpfileComparator()).collect(Collectors.toList());
return listByPlUuid;
}
public static List<UpfileModel> getByPlUuidAndShapeId(String plUuid, String shapeId) {
if (UtilString.isEmpty(plUuid) || UtilString.isEmpty(shapeId)) {
return Collections.emptyList();
}
List<UpfileModel> listByPlUuid = getByPlUuid(plUuid);
if (listByPlUuid.isEmpty()) {
return Collections.emptyList();
}
return listByPlUuid.stream().filter(item -> shapeId.equals(item.getShape_uuid())).collect(Collectors.toList());
}
@Override
protected void load() {
load(this);
}
protected void load(Cache<String, UpfileModel> t) {
UpFileDao upFileDao = new UpFileDao();
List<UpfileModel> _list = upFileDao.queryAll();
if (_list != null && _list.size() > 0) {
for (UpfileModel model : _list) {
t.put(model.getUuid(), model, false);
}
}
LOGGER.info("[{}]Cache加载CoE流程资产库附件配置 [{}个]", SDK.getAppAPI().getAppContext(CoEConstant.APP_ID).getNameI18N(), ((_list == null) ? 0 : _list.size()));
}
static class UpfileComparator implements Comparator<UpfileModel> {
@Override
public int compare(UpfileModel o1, UpfileModel o2) {
// 首先比较创建时间倒序
int createTimeComparison = o2.getCreateTime().compareTo(o1.getCreateTime());
if (createTimeComparison != 0) {
return createTimeComparison;
}
// 如果创建时间相同比较名字默认升序
return o1.getFileName().compareTo(o2.getFileName());
}
}
}

View File

@ -0,0 +1,11 @@
package com.actionsoft.apps.coe.pal.pal.repository.upfile.cache;
import com.actionsoft.apps.coe.pal.pal.repository.upfile.model.UpfileModel;
import com.actionsoft.bpms.commons.cache.ListValueIndex;
public class PALUpfileCacheIndex1 extends ListValueIndex<String, UpfileModel> {
@Override
public String key(UpfileModel upfileModel) {
return upfileModel.getPl_uuid();
}
}

View File

@ -14,4 +14,7 @@ public interface CoeFileConstant {
*/
String COE_UPFILE = "COE_Upfile";
String TMP_UPFILE = "tmp";
String FILE_TYPE_F = "f"; // 模型附件
String FILE_TYPE_S = "s"; // 形状附件
String FILE_TYPE_A = "a"; // 属性附件
}

View File

@ -5,6 +5,8 @@ import com.actionsoft.bpms.commons.database.RowMapper;
import com.actionsoft.bpms.util.DBSql;
import com.actionsoft.bpms.util.UtilString;
import com.actionsoft.exception.AWSDataAccessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
@ -20,6 +22,7 @@ import java.util.Map;
* @version 创建时间2014-4-8
*/
public class UpFileDao {
private static final Logger LOGGER = LoggerFactory.getLogger(UpFileDao.class);
/**
* 创建附件Model
*
@ -251,4 +254,18 @@ public class UpFileDao {
return DBSql.query(sql, new UpfileModelMapper(), new Object[]{uuid, shapeId});
}
}
/**
* 获取所有文件附件
*
* @return
*/
public List<UpfileModel> queryAll() {
String sql = "SELECT * FROM " + UpfileModel.DATABASE_ENTITY;
try {
return DBSql.query(sql, new UpfileModelMapper());
} catch (AWSDataAccessException e) {
LOGGER.error(e.getMessage(), e);
}
return new ArrayList<UpfileModel>();
}
}

View File

@ -3,6 +3,7 @@
*/
package com.actionsoft.apps.coe.pal.pal.repository.upfile.model;
import java.io.Serializable;
import java.sql.Timestamp;
/**
@ -10,7 +11,7 @@ import java.sql.Timestamp;
* @version 创建时间2014-4-8
*
*/
public class UpfileModel {
public class UpfileModel implements Serializable {
public static final String DATABASE_ENTITY = "APP_ACT_COE_PAL_UPFILE";
public static final String FIELD_UUID = "ID";
public static final String FIELD_PL_UUID = "PALREPOSITORYID";
@ -22,6 +23,7 @@ public class UpfileModel {
public static final String FIELD_SECURITY_LEVEL = "SECURITYLEVEL";
public static final String FIELD_CREATEUSER = "CREATEUSER";
public static final String FIELD_CREATETIME = "CREATETIME";
public static final String FIELD_ATTRID = "ATTRID";
private String uuid;
/**
@ -65,6 +67,10 @@ public class UpfileModel {
* 上传时间
*/
private Timestamp createTime;
/**
* 属性id
*/
private String attrId;
/**
* 下载url数据库无该字段后期自行拼装
@ -150,5 +156,12 @@ public class UpfileModel {
public void setCreateTime(Timestamp createTime) {
this.createTime = createTime;
}
public String getAttrId() {
return attrId;
}
public void setAttrId(String attrId) {
this.attrId = attrId;
}
}

View File

@ -0,0 +1,304 @@
package com.actionsoft.apps.coe.pal.pal.repository.upfile.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.actionsoft.apps.coe.pal.components.model.PALSecurityLevelModel;
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
//import com.actionsoft.apps.coe.pal.pal.method.cache.PALMethodAttributeCache;
import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodAttributeModel;
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.upfile.cache.PALUpfileCache;
import com.actionsoft.apps.coe.pal.pal.repository.upfile.constant.CoeFileConstant;
import com.actionsoft.apps.coe.pal.pal.repository.upfile.model.UpfileModel;
import com.actionsoft.apps.coe.pal.pal.repository.util.CoeProcessLevelUtil;
import com.actionsoft.apps.coe.pal.util.HighSecurityUtil;
import com.actionsoft.apps.resource.plugin.profile.DCPluginProfile;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.server.fs.DCContext;
import com.actionsoft.bpms.server.fs.dc.DCProfileManager;
import com.actionsoft.bpms.server.fs.dc.DCUtil;
import com.actionsoft.bpms.util.UtilString;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
/**
* COE 附件上传工具类 处理设计器中 文件附件形状附件 <br/>
* 属性附件参考 {@link MethodAttrUpFileUtil}
*/
public class CoeUpFileUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(CoeUpFileUtil.class);
/**
* DCPluginProfile 对象 COE_Upfile
*/
private static final DCPluginProfile DC_UPFILE_PROFILE = DCProfileManager.getDCProfile(CoEConstant.APP_ID, CoeFileConstant.COE_UPFILE);
/**
* 获取 DCContext
*
* @param uc 用户上下文
* @param model 上传文件模型
*/
public static DCContext getUpFileDCContext(UserContext uc, UpfileModel model) {
DCContext dcContext = null;
if (DC_UPFILE_PROFILE != null) {
if (CoeFileConstant.FILE_TYPE_F.equals(model.getType())) {
// 文件
dcContext = new DCContext(uc, DC_UPFILE_PROFILE, CoEConstant.APP_ID, "file", model.getPl_uuid(), model.getFileName());
} else if (CoeFileConstant.FILE_TYPE_S.equals(model.getType())) {
// 图形
dcContext = new DCContext(uc, DC_UPFILE_PROFILE, CoEConstant.APP_ID, model.getPl_uuid(), model.getShape_uuid(), model.getFileName());
} else {
// 属性
dcContext = MethodAttrUpFileUtil.getDCContext(model, uc);
}
}
return dcContext;
}
/**
* 获取 上传文件的 DCContext
*/
public static DCContext getUpFileDCContext(UserContext uc, String groupValue, String fileValue, String fileName) {
DCContext dcContext = null;
if (DC_UPFILE_PROFILE != null) {
dcContext = new DCContext(uc, DC_UPFILE_PROFILE, CoEConstant.APP_ID, groupValue, fileValue, fileName);
}
return dcContext;
}
//
// /**
// * 获取tmp目录对应DCContext
// * <pre>
// * 文件附件tmp/upfile/uuid/fileName
// * 形状附件tmp/upfile/uuid_shapeId/fileName
// * 文件属性附件tmp/attr_upfile/uuid_attrId/fileName
// * 形状属性附件tmp/attr_upfile/uuid_shapeId_attrId/fileName
// * </pre>
// *
// * @param model 上传文件模型
// */
// public static DCContext getTmpUpFileDCContext(UpfileModel model) {
// return getTmpUpFileDCContext(model.getType(), model.getPl_uuid(), model.getShape_uuid(), model.getAttrId(), model.getFileName());
// }
//
// /**
// * 获取tmp目录对应DCContext
// * <pre>
// * 文件附件tmp/upfile/uuid/fileName
// * 形状附件tmp/upfile/uuid_shapeId/fileName
// * 文件属性附件tmp/attr_upfile/uuid_attrId/fileName
// * 形状属性附件tmp/attr_upfile/uuid_shapeId_attrId/fileName
// * </pre>
// */
// public static DCContext getTmpUpFileDCContext(String type, String plId, String shapeId, String attrId, String fileName) {
// DCContext dcContext = null;
// if (CoeFileConstant.FILE_TYPE_F.equals(type)) {
// // 文件
// dcContext = DCUtil.createTempFileContext(CoEConstant.APP_ID, "upfile", plId, null);
// } else if (CoeFileConstant.FILE_TYPE_S.equals(type)) {
// // 图形
// dcContext = DCUtil.createTempFileContext(CoEConstant.APP_ID, "upfile", plId + "_" + shapeId, null);
// } else if (CoeFileConstant.FILE_TYPE_A.equals(type)) {
// // 属性
// dcContext = MethodAttrUpFileUtil.getTmpUpFileDCContext(plId, shapeId, attrId, fileName);
// }
// // 设置文件名称
// if (dcContext != null) {
// dcContext.setFileName(fileName);
// }
// return dcContext;
// }
//
// /**
// * 将tmp目录中文件移动到COE目录下移动后删除tmp目录文件
// */
// public static void moveTmpFileToCOE(UpfileModel model) {
// DCContext tmpContext = CoeUpFileUtil.getTmpUpFileDCContext(model);
// DCContext coeContext = CoeUpFileUtil.getUpFileDCContext(null, model);
// if (tmpContext != null && coeContext != null) {
// String fName = model.getFileName();
// tmpContext.setFileName(fName);
// coeContext.setFileName(fName);
// if (tmpContext.existFile()) {
// DCUtil.copyDCFile(tmpContext, coeContext);
// tmpContext.delete();
// }
// }
// }
//
// /**
// * 删除DC目录及文件
// *
// * @param dcContext 文件上传 DC对象
// * @throws Exception 异常抛出
// */
// public static void removeUpFileDc(DCContext dcContext) throws Exception {
// if (dcContext != null) {
// dcContext.delete();
// String fName = dcContext.getFileName();
// if (!fName.contains(".")) {
// return;
// }
// String dirName = fName.substring(0, fName.lastIndexOf("."));
// dcContext.setFileName(dirName);
// if (dcContext.existFile()) {
// dcContext.delete();
// }
// // pdf 删除
// if (!fName.endsWith(".pdf")) {
// dcContext.setFileName(dirName + ".pdf");
// if (dcContext.existFile()) {
// dcContext.delete();
// }
// }
// }
// }
//
// /**
// * 组装附件列表信息
// *
// * @param wsId 资产库ID
// * @param methodId 建模方法ID
// * @param plId 模型ID
// * @param fileAttachmentList 文件附件列表
// * @param shapeAttachmentMap 形状附件map数据 key:shapeId,value JSONArray
// * @param relationAttachmentList 文件关联附件列表
// * @param relationShapeAttachmentMap 关联形状附件map数据 key:shapeId,value JSONArray
// */
// public static void wrapperAttachmentList(UserContext uc, String wsId, String methodId, String plId, JSONArray fileAttachmentList, Map<String, JSONArray> shapeAttachmentMap, JSONArray relationAttachmentList, Map<String, JSONArray> relationShapeAttachmentMap) {
// List<UpfileModel> upfileModels = PALUpfileCache.getByPlUuid(plId);
// for (UpfileModel model : upfileModels) {
// String shapeUuid = model.getShape_uuid();
// JSONObject object = wrapperAttachmentObj(uc, model);
// if ("f".equals(model.getType())) {
// fileAttachmentList.add(object);
// } else if ("s".equals(model.getType()) && UtilString.isNotEmpty(shapeUuid)) {
// shapeAttachmentMap.computeIfAbsent(shapeUuid, k -> new JSONArray()).add(object);
// }
// }
// List<DesignerShapeRelationModel> relationModels = DesignerShapeRelationCache.getListByFileId(plId);
// Map<Boolean, List<DesignerShapeRelationModel>> relationModelsMap = relationModels.stream().collect(Collectors.groupingBy(item -> UtilString.isEmpty(item.getShapeId())));
// // 关联附件列表
// List<DesignerShapeRelationModel> fileRelationModels = relationModelsMap.getOrDefault(true, Collections.emptyList());
// List<DesignerShapeRelationModel> shapeRelationModels = relationModelsMap.getOrDefault(false, Collections.emptyList());
//
// // 文件关联附件组装
// List<UpfileModel> relFileUpfileModels = getRelationAttachmentList(wsId, methodId, fileRelationModels);
// relFileUpfileModels.forEach(model -> relationAttachmentList.add(wrapperAttachmentObj(uc, model)));
// // 形状关联附件组装
// Map<String, List<DesignerShapeRelationModel>> shapeRelationModelsMap = shapeRelationModels.stream().filter(item -> UtilString.isNotEmpty(item.getShapeId())).collect(Collectors.groupingBy(DesignerShapeRelationModel::getShapeId));
// for (Map.Entry<String, List<DesignerShapeRelationModel>> entry : shapeRelationModelsMap.entrySet()) {
// String shapeId = entry.getKey();
// List<DesignerShapeRelationModel> models = entry.getValue();
// List<UpfileModel> relShapeUpfileModels = getRelationAttachmentList(wsId, methodId, models);
// relShapeUpfileModels.forEach(model -> {
// // 组装附件信息
// JSONObject object = wrapperAttachmentObj(uc, model);
// relationShapeAttachmentMap.computeIfAbsent(shapeId, k -> new JSONArray()).add(object);
// });
// }
// }
//
// /**
// * 组装附件信息
// */
// public static JSONObject wrapperAttachmentObj(UserContext uc, UpfileModel model) {
// return wrapperAttachmentObj(uc, model, null);
// }
//
// /**
// * 组装附件信息
// */
// public static JSONObject wrapperAttachmentObj(UserContext uc, UpfileModel model, JSONObject refObj) {
// JSONObject object = new JSONObject();
// object.put("fileName", model.getFileName());
// object.put("fileId", model.getUuid());
// object.put("uuid", model.getUuid());
// object.put("attrId", model.getAttrId());
// object.put("shapeId", model.getShape_uuid());
// object.put("download", model.getDownload());
// object.put("securityLevel", model.getSecurityLevel());
// object.put("hasSecurity", true);
// if (HighSecurityUtil.isON() && HighSecurityUtil.fileSecuritySwitch()) {
// int userSecurityLevel = uc.getUserModel().getSecurityLevel();
// PALSecurityLevelModel upFileSecurityLevelInfo = HighSecurityUtil.getUpFileSecurityLevelInfo(model.getUuid());
// int upfileSecurityLevel = Integer.parseInt(upFileSecurityLevelInfo.getCode());
// if (userSecurityLevel < upfileSecurityLevel) {
// object.put("hasSecurity", false);
// }
// object.put("securityInfo", upFileSecurityLevelInfo);
// }
// boolean isDownload = true;
// // 判断ref是否存在
// if (refObj != null) {
// isDownload = refObj.getBooleanValue("isDownload");
// boolean isPreview = refObj.getBooleanValue("isPreview");
// object.put("isDownload", isDownload);
// object.put("isPreview", isPreview);
// }
// String downloadURL = "";
// if (isDownload) {
// DCContext dcContext = CoeUpFileUtil.getUpFileDCContext(uc, model);
// if (dcContext != null) {
// downloadURL = dcContext.getDownloadURL() + "&isInline=false";
// }
// }
// object.put("url", downloadURL);
// return object;
// }
//
// /**
// * 获取当前模型关联的其他模型的附件集合
// */
// public static List<UpfileModel> getRelationAttachmentList(String wsId, String methodId, List<DesignerShapeRelationModel> relationModels) {
// List<UpfileModel> relUpfileModels = new ArrayList<>();
// // attrKey , relationType[ref中的type]
// Map<String, String> relationTypeMap = new HashMap<>();
// // 获取属性列表
// List<PALMethodAttributeModel> attributeList = PALMethodAttributeCache.getListByMethodIdAndWsId(methodId, wsId);
// for (PALMethodAttributeModel model : attributeList) {
// String relationType = "shape";
// if ("relation".equals(model.getType())) {
// JSONObject refObj = JSONObject.parseObject(model.getRef());
// relationType = refObj.containsKey("type") ? refObj.getString("type") : "shape";
// }
// relationTypeMap.put(model.getKey(), relationType);
// }
// for (DesignerShapeRelationModel relationModel : relationModels) {
// String attrId = relationModel.getAttrId();
// if (!relationTypeMap.containsKey(attrId)) {
// continue;
// }
// String type = relationTypeMap.get(attrId);
// if ("file".equals(type)) {
// String relationFileId = relationModel.getRelationFileId();
// PALRepositoryModel uesRelPlModel = CoeProcessLevelUtil.getUseRepositoryByVersionId(relationFileId);
// if (uesRelPlModel != null) {
// List<UpfileModel> useRelUpFileList = PALUpfileCache.getByPlUuid(uesRelPlModel.getId());
// if (!useRelUpFileList.isEmpty()) {
// relUpfileModels.addAll(useRelUpFileList);
// }
// }
// } else {
// List<UpfileModel> useRelUpFileList = PALUpfileCache.getByPlUuidAndShapeId(relationModel.getRelationFileId(), relationModel.getRelationShapeId());
// if (!useRelUpFileList.isEmpty()) {
// relUpfileModels.addAll(useRelUpFileList);
// }
// }
// }
// return relUpfileModels;
// }
}

View File

@ -0,0 +1,125 @@
package com.actionsoft.apps.coe.pal.pal.repository.upfile.util;
import java.util.HashSet;
import java.util.Set;
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
import com.actionsoft.apps.coe.pal.pal.method.constant.PALMethodConst;
import com.actionsoft.apps.coe.pal.pal.repository.upfile.model.UpfileModel;
import com.actionsoft.apps.resource.plugin.profile.DCPluginProfile;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.server.fs.DCContext;
import com.actionsoft.bpms.server.fs.dc.DCProfileManager;
import com.actionsoft.bpms.server.fs.dc.DCUtil;
import com.actionsoft.bpms.util.UtilString;
/**
* @author oYang
* @Description 建模属性附件工具类
* @createTime 2024年03月26日 17:06:00
*/
public class MethodAttrUpFileUtil {
private static final Set<String> audioAndImageTypes = new HashSet<>();
static {
audioAndImageTypes.add("jpg");
audioAndImageTypes.add("jpeg");
audioAndImageTypes.add("png");
audioAndImageTypes.add("gif");
audioAndImageTypes.add("mp3");
audioAndImageTypes.add("mp4");
audioAndImageTypes.add("avi");
}
/**
* 获取DCContext
*
* @param upfileModel 文件模型
* @param userContext 用户上下文
* @return DCContext
*/
public static DCContext getDCContext(UpfileModel upfileModel, UserContext userContext) {
DCPluginProfile dcProfile = DCProfileManager.getDCProfile(CoEConstant.APP_ID, PALMethodConst.ATTR_FILE_DC_REPOSITORY_NAME);
DCContext dcContext = null;
String fileName = upfileModel.getFileName();
if (dcProfile != null) {
if (UtilString.isEmpty(upfileModel.getShape_uuid())) { // 文件属性附件
dcContext = new DCContext(userContext, dcProfile, CoEConstant.APP_ID, upfileModel.getPl_uuid(), upfileModel.getAttrId(), fileName);
} else {
dcContext = new DCContext(userContext, dcProfile, CoEConstant.APP_ID, upfileModel.getPl_uuid(), upfileModel.getShape_uuid() + "_" + upfileModel.getAttrId(), fileName);
}
}
return dcContext;
}
/**
* 获取DCContext
*
* @param dcPluginProfile
* @param userContext
* @param upfileModel
* @return
*/
public static DCContext getDCContext(DCPluginProfile dcPluginProfile, UserContext userContext, UpfileModel upfileModel) {
DCContext dcContext = null;
if (UtilString.isEmpty(upfileModel.getShape_uuid())) { // 文件属性附件
dcContext = new DCContext(userContext, dcPluginProfile, CoEConstant.APP_ID, upfileModel.getPl_uuid(), upfileModel.getAttrId());
} else {
dcContext = new DCContext(userContext, dcPluginProfile, CoEConstant.APP_ID, upfileModel.getPl_uuid(), upfileModel.getShape_uuid() + "_" + upfileModel.getAttrId());
}
return dcContext;
}
//
// /**
// * 获取属性附件临时目录
// * <pre>
// * 文件属性附件tmp/attr_upfile/uuid_attrId/fileName
// * 形状属性附件tmp/attr_upfile/uuid_shapeId_attrId/fileName
// * </pre>
// *
// * @return DCContext 对象
// */
// public static DCContext getTmpUpFileDCContext(UpfileModel upfileModel) {
// DCContext dcContext;
// if (UtilString.isEmpty(upfileModel.getShape_uuid())) {
// // 文件属性附件
// dcContext = DCUtil.createTempFileContext(CoEConstant.APP_ID, PALMethodConst.ATTR_FILE_DC_REPOSITORY_NAME, upfileModel.getPl_uuid() + "_" + upfileModel.getAttrId(), upfileModel.getFileName());
// } else {
// dcContext = DCUtil.createTempFileContext(CoEConstant.APP_ID, PALMethodConst.ATTR_FILE_DC_REPOSITORY_NAME, upfileModel.getPl_uuid() + "_" + upfileModel.getShape_uuid() + "_" + upfileModel.getAttrId(), upfileModel.getFileName());
// }
// return dcContext;
// }
//
// /**
// * 获取属性附件临时目录
// * <pre>
// * 文件属性附件tmp/attr_upfile/uuid_attrId/fileName
// * 形状属性附件tmp/attr_upfile/uuid_shapeId_attrId/fileName
// * </pre>
// *
// * @return DCContext 对象
// */
// public static DCContext getTmpUpFileDCContext(String plId, String shapeId, String attrId, String fileName) {
// DCContext dcContext;
// if (UtilString.isEmpty(shapeId)) {
// // 文件属性附件
// dcContext = DCUtil.createTempFileContext(CoEConstant.APP_ID, PALMethodConst.ATTR_FILE_DC_REPOSITORY_NAME, plId + "_" + attrId, null);
// } else {
// dcContext = DCUtil.createTempFileContext(CoEConstant.APP_ID, PALMethodConst.ATTR_FILE_DC_REPOSITORY_NAME, plId + "_" + shapeId + "_" + attrId, null);
// }
// dcContext.setFileName(fileName);
// return dcContext;
// }
//
// /**
// * 判断文件类型是否是音频或图片
// *
// * @param fileType 文件类型
// * @return true/false
// */
// public static boolean predicateFileTypeIsAudioOrImage(String fileType) {
// return audioAndImageTypes.contains(fileType);
// }
}

View File

@ -2611,6 +2611,9 @@ public class CoeProcessLevelWeb extends ActionWeb {
plLevel = plModel.getLevel();
plOrderIndex = plModel.getOrderIndex();
methodId = plModel.getMethodId();
if ("freedom.allmethod".equals(methodId)){
macroLibraries.put("classification", I18nRes.findValue(CoEConstant.APP_ID, methodId));
}
for (int i = 0, methodSize = methodModels.size(); i < methodSize; i++) {
PALMethodModel palMethodModel = methodModels.get(i);
String appId = palMethodModel.getId();
@ -8623,7 +8626,12 @@ public class CoeProcessLevelWeb extends ActionWeb {
* @param methodId
* @return
*/
public String getPalProcessLevelCreateMethodList(String category, String methodId) {
public String getPalProcessLevelCreateMethodList(String category, String methodId, String fileId) {
if(!"process.framework".equals(methodId) && !"default".equals(methodId)){//不是架构或者文件夹
ResponseObject ro = ResponseObject.newErrResponse();
ro.msg("methodId"+methodId+"当前所选择目录不是文件夹或者流程架构,请选择正确的目录!");
return ro.toString();
}
ResponseObject ro = ResponseObject.newOkResponse();
JSONArray fileArr = new JSONArray();// 文件类模型可以画图
JSONArray folderArr = new JSONArray();// 文件夹类模型作为文件夹
@ -8659,16 +8667,29 @@ public class CoeProcessLevelWeb extends ActionWeb {
methodObj.put("categoryName", I18nRes.findValue(CoEConstant.APP_ID, c));
methodObj.put("method", model.getId());
methodObj.put("methodName", I18nRes.findValue(CoEConstant.APP_ID, model.getId()));
if (model.getSchema().contains("架构KPI图")) {
methodObj.put("methodName", "架构KPI图");
}
if (model.getSchema().contains("角色图")) {
methodObj.put("methodName", "角色图");
if (!"freedom.allmethod".equals(model.getId())){
if (model.getSchema().contains("架构KPI图")){
methodObj.put("methodName", "架构KPI图");
}
if (model.getSchema().contains("角色图")){
methodObj.put("methodName", "角色图");
}
}
// System.out.println(c+"对应的"+ PALMethodManager.getInstance().havingCreateMethodPerm(category, methodId, "process", model.getId()));
//流程入口允许新建表单图和制度图 by金鹏
if (category.equals("process") && model.getSchema().contains("表单图")) {
if (model.getId().equals("freedom.allmethod")) {
if (StringUtils.isBlank(fileId)){
methodObj.put("havingCreatePerm", false);
}else {
String property = SDK.getAppAPI().getProperty(CoEConstant.APP_ID, "freedom.file");
if (StringUtils.isNotBlank(property)&&property.contains(fileId)){
methodObj.put("havingCreatePerm", true);
}else {
methodObj.put("havingCreatePerm", false);
}
}
}else if (category.equals("process") && model.getSchema().contains("表单图")) {
methodObj.put("havingCreatePerm", true);
} else if (category.equals("process") && model.getSchema().contains("制度")) {
methodObj.put("havingCreatePerm", true);
@ -11709,9 +11730,10 @@ public class CoeProcessLevelWeb extends ActionWeb {
PALRepositoryCache.getAllChildrenModelsByPid(model.getWsId(), model.getId(), childList, ids);
removeList.addAll(childList);
for (PALRepositoryModel removeModel : removeList) {
//普通用户不允许删除已发布的文件
if (removeModel.isPublish() && !"admin".equals(_uc.getUID())) {
return ResponseObject.newErrResponse("已发布文件["+ removeModel.getName() + VersionUtil.getVersionStrV(removeModel.getVersion()) + "]不允许删除,请联系系统管理员!").toString();
//校验禁止删除逻辑
String errorResponse = checkRemovalPermission(removeModel, _uc);
if (errorResponse != null) {
return errorResponse;
}
}
@ -13210,6 +13232,18 @@ public class CoeProcessLevelWeb extends ActionWeb {
return ro.toString();
}
// 提取重复的错误判断逻辑到一个方法中
private String checkRemovalPermission(PALRepositoryModel model, UserContext _uc) {
if ("admin".equals(_uc.getUID())) {
return null;
}
//非设计状态即草稿不允许删除
if (model.isPublish() || model.isStop() || model.isApproval()) {
return ResponseObject.newErrResponse("文件[" + model.getName() + VersionUtil.getVersionStrV(model.getVersion()) + "]非草稿状态不允许删除,请联系系统管理员!").toString();
}
return null;
}
class ComparatorMap implements Comparator<PALRepositoryModel> {
@Override
@ -13221,4 +13255,6 @@ public class CoeProcessLevelWeb extends ActionWeb {
}
}

View File

@ -63,6 +63,8 @@ import com.actionsoft.apps.coe.pal.pal.manage.publish.cache.PublishUserGroupCach
import com.actionsoft.apps.coe.pal.pal.manage.publish.cache.PublishUserGroupPermCache;
import com.actionsoft.apps.coe.pal.pal.manage.publish.cache.PublishUserGroupRoleCache;
import com.actionsoft.apps.coe.pal.pal.method.aslp.RegisterMethodApp;
import com.actionsoft.apps.coe.pal.pal.method.cache.PALBasicMethodCache;
import com.actionsoft.apps.coe.pal.pal.method.cache.PALMethodSchemaCache;
import com.actionsoft.apps.coe.pal.pal.output.aslp.RegisterOutputApp;
import com.actionsoft.apps.coe.pal.pal.repository.addons.RepositoryDiagramExistMark;
import com.actionsoft.apps.coe.pal.pal.repository.cache.CoeProcessLevelCorrelateCache;
@ -80,6 +82,7 @@ import com.actionsoft.apps.coe.pal.pal.repository.designer.realtime.manage.CoeLi
import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.cache.DesignerShapeRelationCache;
import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.manager.DesignerShapeCopyCache;
import com.actionsoft.apps.coe.pal.pal.repository.upfile.CoeFileProcessor;
import com.actionsoft.apps.coe.pal.pal.repository.upfile.cache.PALUpfileCache;
import com.actionsoft.apps.coe.pal.pal.repository.upfile.constant.CoeFileConstant;
import com.actionsoft.apps.coe.pal.teamwork.cache.TeamMemberPermCache;
import com.actionsoft.apps.coe.pal.teamwork.cache.TeamPermCache;
@ -134,6 +137,9 @@ public class Plugins implements PluginListener {
list.add(new CachePluginProfile(CoeCooperationTeamPermCache.class));
list.add(new CachePluginProfile(CoeCooperationRoleCache.class));
list.add(new CachePluginProfile(CoeCooperationRolePermCache.class));
list.add(new CachePluginProfile(PALUpfileCache.class));
list.add(new CachePluginProfile(PALBasicMethodCache.class));
list.add(new CachePluginProfile(PALMethodSchemaCache.class));
list.add(new AtFormulaPluginProfile("PAL应用", "@getDWCondition(*fieldName,*fieldValue)", GetDWConditionExpression.class.getName(), "获取DW中的自定义查询条件", "返回DW中自定义的查询条件"));

View File

@ -0,0 +1,171 @@
package com.actionsoft.apps.coe.pal.util;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.actionsoft.bpms.server.fs.DCContext;
import com.actionsoft.bpms.util.Base64;
import com.actionsoft.sdk.local.SDK;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
/**
* COE处理DC工具类
*/
public class CoeDcUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(CoeDcUtil.class);
/**
* 类型转换 {@link DCContext } 转换为 {@link JSONArray} <br/>
* DC判空且判断DC文件是否存在不存在则返回 null
*
* @return 返回 JSONArray 若为空则返回 null
*/
public static JSONArray dcContextToJa(DCContext dcContext) {
if (dcContext == null || !dcContext.existFile()) {
return null;
}
InputStream read = SDK.getDCAPI().read(dcContext);
return inputStreamToJa(read);
}
/**
* 类型转换 {@link DCContext } 转换为 {@link JSONObject} <br/>
* DC判空且判断DC文件是否存在不存在则返回 null
*
* @return 返回 JSONObject 若为空则返回 null
*/
public static JSONObject dcContextToJo(DCContext dcContext) {
if (dcContext == null || !dcContext.existFile()) {
return null;
}
InputStream read = SDK.getDCAPI().read(dcContext);
return inputStreamToJo(read);
}
/**
* 类型转换 {@link DCContext } 转换为 {@link String} <br/>
* DC判空且判断DC文件是否存在不存在则返回 null
*
* @return 返回 String 若为空则返回 "";
*/
public static String dcContextToString(DCContext dcContext) {
if (dcContext == null || !dcContext.existFile()) {
return "";
}
InputStream read = SDK.getDCAPI().read(dcContext);
return inputStreamToString(read);
}
/**
* 类型转换 {@link DCContext } 转换为 {@link String} <br/>
* DC判空且判断DC文件是否存在不存在则返回 null
*
* @return 返回 byte 若为空则返回 null
*/
public static byte[] dcContextToByte(DCContext dcContext) {
if (dcContext == null || !dcContext.existFile()) {
return null;
}
InputStream read = SDK.getDCAPI().read(dcContext);
return inputStreamToByte(read);
}
/**
* 类型转换 {@link DCContext } 转换为 base64 数据 {@link String} <br/>
* DC判空且判断DC文件是否存在不存在则返回 null <br/>
* 携带前缀data:image/png;base64,
*
* @return 返回 byte 若为空则返回 null
*/
public static String dcContextToBase64(DCContext dcContext) {
byte[] bytes = dcContextToByte(dcContext);
if (bytes == null) {
return null;
}
byte[] base64Bytes = Base64.encode(bytes);
return "data:image/png;base64," + new String(base64Bytes, StandardCharsets.UTF_8);
}
/**
* 类型转换 {@link InputStream } 转换为 {@link JSONArray}
*
* @return 返回 JSONArray 若为空则返回 null
*/
public static JSONArray inputStreamToJa(InputStream inputStream) {
String str = inputStreamToString(inputStream);
try {
return JSONArray.parseArray(str);
} catch (Exception e) {
LOGGER.error("inputStream[{}]格式不正确转换JSONArray[失败]", str, e);
return null;
}
}
/**
* 类型转换 {@link InputStream } 转换为 {@link JSONObject}
*
* @return 返回 JSONObject 若为空则返回 null
*/
public static JSONObject inputStreamToJo(InputStream inputStream) {
String str = inputStreamToString(inputStream);
try {
return JSON.parseObject(str);
} catch (Exception e) {
LOGGER.error("inputStream[{}]格式不正确转换JSONObject[失败]", str, e);
return null;
}
}
/**
* 类型转换 {@link InputStream } 转换为 {@link String}
*
* @return 返回 String 若为空则返回 null
*/
public static String inputStreamToString(InputStream inputStream) {
if (inputStream == null) {
return null;
}
try {
return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
return null;
}
}
/**
* 类型转换 {@link InputStream } 转换为 byte[]
*
* @return 返回 byte[] 若为空则返回 null
*/
public static byte[] inputStreamToByte(InputStream inputStream) {
if (inputStream == null) {
return null;
}
try {
return IOUtils.toByteArray(inputStream);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
return null;
}
}
/**
* 数据写入 DC
*/
public static boolean write(String define, DCContext dcContext) {
if (define == null || dcContext == null) {
return false;
}
return SDK.getDCAPI().write(new ByteArrayInputStream(define.getBytes(StandardCharsets.UTF_8)), dcContext);
}
}

View File

@ -13,6 +13,10 @@ import com.actionsoft.i18n.I18nRes;
import com.actionsoft.sdk.local.SDK;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.actionsoft.apps.coe.pal.components.model.PALSecurityLevelModel;
import com.actionsoft.apps.coe.pal.pal.repository.upfile.cache.PALUpfileCache;
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
import com.actionsoft.exception.AWSException;
import java.lang.reflect.Field;
import java.util.*;
@ -222,5 +226,65 @@ public class HighSecurityUtil {
boolean fileSwitch = Boolean.parseBoolean(param);
return fileSwitch;
}
/**
* 获取附件密级信息
*
* @param upfileId 附件Id
* @return 密级信息
*/
public static PALSecurityLevelModel getUpFileSecurityLevelInfo(String upfileId) {
UpfileModel upfileModel = PALUpfileCache.getCache().get(upfileId);
Integer securityLevel = upfileModel.getSecurityLevel();
return getSecurityLevelModel(securityLevel);
}
private static PALSecurityLevelModel getSecurityLevelModel(Integer securityLevel) {
if (securityLevel == null || securityLevel == -1) {
return new PALSecurityLevelModel("-1", I18nRes.findValue(CoEConstant.APP_ID, "未标密"), "#f56c6c");
}
Map<String, PALSecurityLevelModel> securityInfoMap = getSecurityInfoMap();
PALSecurityLevelModel userSecurityInfo = securityInfoMap.get(String.valueOf(securityLevel));
if (userSecurityInfo == null) {
return new PALSecurityLevelModel("-1", I18nRes.findValue(CoEConstant.APP_ID, "未知密级"), "#f56c6c");
}
return userSecurityInfo;
}
/**
* 获取密级列表Map
*
* @return 密级列表Map
*/
public static Map<String, PALSecurityLevelModel> getSecurityInfoMap() {
Map<String, PALSecurityLevelModel> map = new HashMap<>();
if (isON()) {
// 获取平台的对象秘级参数设置
HashMap<String, String> securityMap = getObjSecurityMap();
// 获取PAL应用参数密级颜色设置
JSONObject highSecurityFontStyle = getHighSecurityFontStyle();
Set<Map.Entry<String, String>> entries = securityMap.entrySet();
for (Map.Entry<String, String> entry : entries) {
String key = entry.getKey();
String value = entry.getValue();
JSONObject colorObject = highSecurityFontStyle.getJSONObject(key);
String color = "";
if (colorObject != null) {
color = colorObject.getString("color");
}
PALSecurityLevelModel palSecurityLevelModel = new PALSecurityLevelModel(key, value, color);
map.put(key, palSecurityLevelModel);
}
}
return map;
}
/**
* 获取密级样式设置
*
* @return
*/
public static JSONObject getHighSecurityFontStyle() {
JSONObject highSecurityFontStyle = SDK.getAppAPI().getPropertyJSONObjectValue(CoEConstant.APP_ID, "HighSecurityFontStyle", new JSONObject());
if (highSecurityFontStyle == null || highSecurityFontStyle.isEmpty()) {
throw new AWSException("请设置密级样式");
}
return highSecurityFontStyle;
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,280 @@
<!DOCTYPE html >
<html xmlns=http://www.w3.org/1999/xhtml>
<head>
<title><#fileName></title>
<meta charset="UTF-8">
<link rel="stylesheet" href="../commons/css/awsui.css">
<link type='text/css' rel='stylesheet' href='../apps/com.actionsoft.apps.coe.pal/lib/designer/themes/default/diagraming/designer.versionCompare.css' />
<script type='text/javascript' src='../commons/js/jquery/scripts/jquery.js'></script>
<script type="text/javascript" src="../commons/js/awsui.js"></script>
<script type='text/javascript' charset='UTF-8' src='../apps/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/schema/schema.js'></script>
<!-- 版本对比 -->
<script type='text/javascript' charset='UTF-8' src='../apps/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/versionCompare/version.core.debug.js'></script>
<script>
var 修改 = "<I18N#修改>"
var 由 = "<I18N#>"
var 设计中 = "<I18N#设计中>"
var 已发布 = "<I18N#已发布>"
var 已停用 = "<I18N#已停用>"
var 审核中 = "<I18N#审核中>"
var 设计 = "<I18N#设计>"
var 文件属性 = "<I18N#文件属性>"
var 文件信息 = "<I18N#文件信息>";
var 附件 = "<I18N#附件>"
var 形状属性 = "<I18N#形状属性>"
var 数据属性 = "<I18N#数据属性>"
var 链接 = "<I18N#链接>"
var 暂无文件属性 = "<I18N#暂无文件属性>"
var 关联附件 = "<I18N#关联附件>"
var 暂无形状属性 = "<I18N#暂无形状属性>"
var 文件链接 = "<I18N#文件链接>"
var 自定义链接 = "<I18N#自定义链接>"
var 暂无 = "<I18N#暂无>"
var 预览 = "<I18N#预览>"
var 正在切换 = "<I18N#正在切换>"
var 是否将 = "<I18N#是否将>"
var 切换为使用中 = "<I18N#切换为使用中>"
var 图元位于画布左侧可解除同步锁定查看 = "<I18N#图元位于画布左侧可解除同步锁定查看>"
var 图元位于画布右侧可解除同步锁定查看 = "<I18N#图元位于画布右侧可解除同步锁定查看>"
var 图元位于画布顶部可解除同步锁定查看 = "<I18N#图元位于画布顶部可解除同步锁定查看>"
var 图元位于画布底部可解除同步锁定查看 = "<I18N#图元位于画布底部可解除同步锁定查看>"
var 同步版本间操作 = "<I18N#同步版本间操作>"
var 关闭缩略图 = "<I18N#关闭缩略图>"
var 显示缩略图 = "<I18N#显示缩略图>"
var 缩小 = "<I18N#缩小>"
var 重置 = "<I18N#重置>"
var 放大 = "<I18N#放大>"
var 新增图元 = "<I18N#新增图元>"
var 删除图元 = "<I18N#删除图元>"
var 图元位置变化 = "<I18N#图元位置变化>"
var 图元信息变化 = "<I18N#图元信息变化>"
var 图元名称样式变化 = "<I18N#图元名称样式变化>"
var isProcessExec = <#isProcessExec> // 版本对比页面与梳理到执行流程对比页面共用 以此进行区分 方便页面屏蔽一些逻辑与数据
// 是否用于bpm隐藏属性、隐藏返回按钮
var ifHideUI = <#ifHideUI>
var versionData = <#versionData>
var curData = <#curData>
var pageDefinition = {
left: JSON.parse(versionData.definition),
right: JSON.parse(curData.definition)
}
var leftOfRelationShapes = <#leftOfRelationShapes>
var rightOfRelationShapes = <#rightOfRelationShapes>
var methodId = "<#methodId>"
var methodIcon = <#methodIcon>
var fileName = "<#fileName>"
var relationShapeInfo = {
left: leftOfRelationShapes,
right: rightOfRelationShapes
}
var isSameOperate = true // 同步版本间操作
var diffList = <#diffNode>
var diffNode = diffList.filter(i => i.type.length > 0)
$(document).ready(function () {
$('.method-icon').append('<i class="awsui-iconfont">' + methodIcon.code + '</i>');
$('.method-icon').css({background: methodIcon.color});
$('.file-name').text(fileName)
$('.version-num-left').text(versionData.versionNo)
$('.version-num-right').text(curData.versionNo)
$('.update-time-left').text(versionData.updateTime)
$('.update-time-right').text(curData.updateTime)
// 悬浮icon
$('.attribute-view-btn').off("mouseenter").on("mouseenter", function () {
let pos = $(this).attr('position')
let str = Utils.getSelected(pos).length > 0 ? 数据属性 : 文件信息
let html = `<div class="btn-text">${str}</div>`
if($(this).find('.btn-text').length === 0) {
$(this).css('width', 'auto')
$(this).append(html)
}
}).off("mouseleave").on("mouseleave", function () {
$(this).css('width', '40px')
$(this).find('.btn-text').remove()
})
// 梳理到执行
if (isProcessExec) {
// 继续编辑按钮 屏蔽
$('.left-right').css('visibility', 'hidden')
// 左侧版本下拉列表 屏蔽
$('.left .left-center .center-top i.awsui-iconfont').css('visibility', 'hidden')
}
if (ifHideUI) {
// 属性侧边栏 屏蔽
$('.attribute-view-btn').hide()
// 返回按钮 屏蔽
$('.back-icon').hide()
}
$('.same-operate').attr('awsui-qtip', 同步版本间操作)
$('.close-nav-icon').attr('awsui-qtip', 关闭缩略图)
$('.show-nav-icon').attr('awsui-qtip', 显示缩略图)
$('.zoom-in-icon').attr('awsui-qtip', 放大)
$('.zoom-value').attr('awsui-qtip', 重置)
$('.zoom-out-icon').attr('awsui-qtip', 缩小)
})
// 左侧 版本切换显示隐藏的开关处理通过iframe url传递 isHistory 参数
$("#leftChangeVersion").ready(function () {
let urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('isHistory') === 'true') {
let leftChangeVersion = $("#leftChangeVersion");
leftChangeVersion.css("visibility", "hidden");
}
})
// 点击其他触发
document.addEventListener('click', function(event) {
// 关闭版本列表
versionCompareFun.closeVersionListByClick(event)
});
</script>
<script type='text/javascript' charset='UTF-8' src='../apps/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/versionCompare/version.methods.debug.js'></script>
</head>
<body style="overflow: hidden;margin: 0">
<div class="page-head flex-center">
<div class="left flex-center">
<div>
<span class="back-icon" style="cursor: pointer" onclick="versionListFun.closeComparePage()"><i class="awsui-iconfont">&#xe715;</i></span>
<span class="method-icon"></span>
<span class="file-name" style="font-size: 20px"></span>
</div>
<div class="left-center" style="position:relative;">
<div class="center-top">
<span class="version-num-left"></span>
<i class="awsui-iconfont" style="font-size: 12px" onclick="versionCompareFun.openCompareList()">&#xe716;</i>
</div>
<div class="update-time update-time-left"></div>
<div id="compareVersionList" class="compare-version-list" style="display:none;"></div>
</div>
<div id="leftChangeVersion" class="left-right" onclick="versionCompareFun.changeToSelectedV()">
<I18N#切换到该版本>
</div>
</div>
<div class="same-operate opend-operate" awsui-qtip="同步版本间操作" onclick="versionCompareFun.isOpenSameOperate(false)">
<i class="awsui-iconfont">&#xe7b3;</i>
</div>
<div class="same-operate closed-operate" style="display:none;" awsui-qtip="同步版本间操作" onclick="versionCompareFun.isOpenSameOperate(true)">
<i class="awsui-iconfont">&#xe7bc;</i>
</div>
<div class="right flex-center">
<div></div>
<div class="left-center">
<div class="center-top version-num-right"></div>
<div class="update-time update-time-right"></div>
</div>
<div class="left-right" onclick="versionListFun.closeComparePage()">
<span><I18N#继续编辑></span>
</div>
</div>
</div>
<div style="display: flex;">
<div class="designer-wrapper" style="border-right: 1px solid #666">
<div id="designer-layout-left" class="version-designer-layout" position="left">
<div id="canvas-container-left" class="version-canvas_container" >
<div id="designer-canvas-left" class="version-canvas">
<canvas id="designer-grids-left"></canvas>
</div>
</div>
</div>
<!-- 悬浮按钮 -->
<div id="view-btn-left" position="left" class="attribute-view-btn" onclick="versionCompareFun.openAttributeView('left')">
<div class="btn-icon">
<i class="awsui-iconfont" style="font-size: 20px">&#xe698;</i>
</div>
</div>
<!-- 文件信息 -->
<div id="attribute-view-left" class="attribute-view">
<div class="view-head">
<div class="head-left" viewType="file"></div>
<div class="head-right">
<i class="awsui-iconfont" onclick="versionCompareFun.closeAttributeView('left')">&#xe633;</i>
</div>
</div>
<div id="view-body-left" class="view-body"></div>
</div>
<!-- 文件预览 -->
<div id="file-preview-left">
<img style="width: 100%;height: 93%;object-fit: contain"/>
</div>
<!-- 图元不在可视区域范围提示 -->
<div class="shape-tip shape-tip-left"><I18N#图元位于画布左侧可解除同步锁定查看></div>
</div>
<div class="designer-wrapper">
<div id="designer-layout-right" class="version-designer-layout" position="right">
<div id="canvas-container-right" class="version-canvas_container" >
<div id="designer-canvas-right" class="version-canvas">
<canvas id="designer-grids-right"></canvas>
</div>
</div>
</div>
<div id="view-btn-right" position="right" class="attribute-view-btn" onclick="versionCompareFun.openAttributeView('right')">
<div class="btn-icon">
<i class="awsui-iconfont" style="font-size: 20px">&#xe698;</i>
</div>
</div>
<div id="attribute-view-right" class="attribute-view">
<div class="view-head">
<div class="head-left" viewType="file"></div>
<div class="head-right">
<i class="awsui-iconfont" onclick="versionCompareFun.closeAttributeView('right')">&#xe633;</i>
</div>
</div>
<div id="view-body-right" class="view-body"></div>
</div>
<div id="file-preview-right">
<img style="width: 100%;height: 93%;object-fit: contain"/>
</div>
<div class="shape-tip shape-tip-right"><I18N#图元位于画布左侧可解除同步锁定查看></div>
</div>
</div>
<div class="version-footer">
<div class="footer-half" style="border-right: 1px solid #666">
<span><i class="awsui-iconfont close-nav-icon" style="display: none" id="close-nav-left" awsui-qtip="关闭缩略图" onclick="versionCompareFun.openNavigation('left',false)">&#xe603;</i></span>
<span><i class="awsui-iconfont show-nav-icon" awsui-qtip="显示缩略图" id="show-nav-left" onclick="versionCompareFun.openNavigation('left',true)">&#xe603;</i></span>
<span><i class="awsui-iconfont zoom-out-icon" awsui-qtip="缩小" onclick="versionCompareFun.pageZoom('left','zoomOut')">&#xe715;</i></span>
<span id="zoom-value-left" class="zoom-value" awsui-qtip="重置" onclick="versionCompareFun.pageZoom('left','reset')">100%</span>
<span><i class="awsui-iconfont zoom-in-icon" awsui-qtip="放大" onclick="versionCompareFun.pageZoom('left','zoomIn')">&#xe717;</i></span>
<!-- 鹰眼导航 -->
<div id="navigation-view-left" class="version-dock_view">
<div class="navigation_bounding">
<div class="navigation_view_container">
<canvas id="navigation-canvas-left" width="120px" height="160px" class="navigation_canvas"></canvas>
<div id="navigation-eye-left" class="navigation_eye"></div>
</div>
</div>
</div>
</div>
<div class="footer-half">
<span><i class="awsui-iconfont close-nav-icon" style="display: none" id="close-nav-right" awsui-qtip="关闭缩略图" onclick="versionCompareFun.openNavigation('right',false)">&#xe603;</i></span>
<span><i class="awsui-iconfont show-nav-icon" awsui-qtip="显示缩略图" id="show-nav-right" onclick="versionCompareFun.openNavigation('right',true)">&#xe603;</i></span>
<span><i class="awsui-iconfont zoom-out-icon" awsui-qtip="缩小" onclick="versionCompareFun.pageZoom('right','zoomOut')">&#xe715;</i></span>
<span id="zoom-value-right" class="zoom-value" awsui-qtip="重置" onclick="versionCompareFun.pageZoom('right','reset')">100%</span>
<span><i class="awsui-iconfont zoom-in-icon" awsui-qtip="放大" onclick="versionCompareFun.pageZoom('right','zoomIn')">&#xe717;</i></span>
<div id="navigation-view-right" class="version-dock_view">
<div class="navigation_bounding">
<div class="navigation_view_container">
<canvas id="navigation-canvas-right" width="120px" height="160px" class="navigation_canvas"></canvas>
<div id="navigation-eye-right" class="navigation_eye"></div>
</div>
</div>
</div>
</div>
</div>
<div id="model-left" class="dialog-model" style="display: none;left: 0"></div>
<div id="model-right" class="dialog-model" style="display: none;right: 0"></div>
</body>
</html>

View File

@ -8,6 +8,7 @@
<link type='text/css' rel='stylesheet' href='../apps/com.actionsoft.apps.coe.pal/lib/designer/themes/default/global_zh.css' />
<link type='text/css' rel='stylesheet' href='../apps/com.actionsoft.apps.coe.pal/lib/designer/themes/default/diagraming/designer.css' />
<link type='text/css' rel='stylesheet' href='../apps/com.actionsoft.apps.coe.pal/lib/designer/themes/default/diagraming/ui.css' />
<link type='text/css' rel='stylesheet' href='../apps/com.actionsoft.apps.coe.pal/lib/designer/themes/default/diagraming/designer.versionCompare.css' />
<link rel="stylesheet" href="../commons/css/awsui.css">
<style>
.button.blue {
@ -176,6 +177,100 @@
<script type='text/javascript' src='../commons/js/jquery/scripts/jquery.js'></script>
<script type="text/javascript" src="../commons/js/jquery/scripts/jquery-migrate.js"></script>
<script type='text/javascript' charset='UTF-8' src='../apps/com.actionsoft.apps.coe.pal/lib/designer/scripts/util.js'></script>
<!-- i18n -->
<script>
var 快速查询 = "<I18N#快速查询>";
var 已保存成功 = "<I18N#已保存成功>";
var 保存成功 = "<I18N#保存成功>";
var 页面中有未保存的内容请先保存 = "<I18N#页面中有未保存的内容请先保存>";
var 保存失败 = "<I18N#保存失败>";
var 列的第 = "<I18N#列的第>";
var 行不允许为空 = "<I18N#行不允许为空>";
var 文件属性 = "<I18N#文件属性>";
var 不允许为空 = "<I18N#不允许为空>";
var 返回 = "<I18N#返回>";
var 版本号 = "<I18N#版本号>";
var 吸色 = "<I18N#吸色>";
var 退出 = "<I18N#退出>";
var 当前颜色 = "<I18N#当前颜色>";
$(document).ready(function(){
$("#queryInput").attr("placeholder", 快速查询);
$("#back-vue-page-span").attr("awsui-qtip", 返回);
$("#toolbar_designer_version_no").attr("awsui-qtip", 版本号);
$("#color_draw").attr("awsui-qtip", 吸色 + "Esc" + 退出);
$("#color_show_now").attr("awsui-qtip", 当前颜色);
});
// designer.ui.debug.js i18n
var 颜色渐变 = "<I18N#颜色渐变>";
var 起始版本 = "<I18N#起始版本>";
var 错误个数 = "<I18N#错误个数>";
var 校验通过 = "<I18N#校验通过>";
var 文件过大不允许超过 = "<I18N#文件过大, 不允许超过>";
var 上传成功 = "<I18N#上传成功>";
var 正在加载预览 = "<I18N#正在加载预览>";
var 此地址下无法加载图片 = "<I18N#此地址下无法加载图片>";
var 请检查图片地址是否正确 = "<I18N#请检查图片地址是否正确>";
var 确保图片地址处于公开状态 = "<I18N#确保图片地址处于公开状态>";
var 正在加载图片 = "<I18N#正在加载图片>";
var 显示更多结果 = "<I18N#显示更多结果>";
var 正在应用图片请稍候 = "<I18N#正在应用图片请稍候>";
var 无法使用此图片请选择其他图片 = "<I18N#无法使用此图片请选择其他图片>";
var 页面中有未保存的内容请先保存 = "<I18N#页面中有未保存的内容请先保存>";
var 请稍后 = "<I18N#请稍后>";
var 请您先保存一个版本 = "<I18N#请您先保存一个版本>";
var 预览 = "<I18N#预览>";
var 图片创建完成 = "<I18N#图片创建完成>";
var 是否打开图片预览 = "<I18N#是否打开图片预览>";
var 导出完成 = "<I18N#导出完成>";
var 确定 = "<I18N#确定>";
var 关闭 = "<I18N#关闭>";
var 节点编号排序 = "<I18N#节点编号排序>";
var 提示 = "<I18N#提示>";
var 拖动排序确定后请保存设计器 = "<I18N#拖动排序确定后请保存设计器>";
var 无名称 = "<I18N#无名称>";
var 不支持编号排序 = "<I18N#不支持编号排序>";
var 画布没有形状或者形状没有编号属性 = "<I18N#画布没有形状或者形状没有编号属性>";
var 名称 = "<I18N#名称>";
var 节点号 = "<I18N#节点号>";
var 新发布 = "<I18N#新发布>";
var 变更 = "<I18N#变更>";
var 停用 = "<I18N#停用>";
var 暂无发布历史 = "<I18N#暂无发布历史>";
var 文件链接 = "<I18N#文件链接>";
var 自定义链接 = "<I18N#自定义链接>";
var 暂无链接 = "<I18N#暂无链接>";
var 处修改 = "<I18N#处修改>";
var 暂停 = "<I18N#暂停>";
var 从此版本播放 = "<I18N#从此版本播放>";
var 浏览器限制无法进入演示视图 = "<I18N#浏览器限制无法进入演示视图>";
var 无法进入全屏视图您可以按F11进入 = "<I18N#无法进入全屏视图您可以按(F11)进入>";
var 秒后自动保存 = "<I18N#秒后自动保存>";
var 修改 = "<I18N#修改>"
var 由 = "<I18N#>"
var 创建 = "<I18N#创建>"
var 新建版本 = "<I18N#新建版本>"
var 版本对比 = "<I18N#版本对比>"
var 切换该版本 = "<I18N#切换该版本>"
var 设计中 = "<I18N#设计中>"
var 已发布 = "<I18N#已发布>"
var 已停用 = "<I18N#已停用>"
var 审核中 = "<I18N#审核中>"
var 设计 = "<I18N#设计>"
var 是否继续切换 = "<I18N#是否继续切换>"
var 历史版本 = "<I18N#历史版本>"
var 提示 = "<I18N#提示>"
var 确定将 = "<I18N#确定将>"
var 版本为模板创建新版本文件 = "<I18N#版本为模板创建新版本文件>"
var 历史版本为模板创建新版本文件 = "<I18N#历史版本为模板创建新版本文件>"
var 请选择版本号 = "<I18N#请选择版本号>"
var 文件修改未保存 = "<I18N#文件修改未保存>"
var 文件已修改未保存 = "<I18N#文件已修改未保存>"
var 附件 = "<I18N#附件>"
var 形状属性 = "<I18N#形状属性>"
var 链接 = "<I18N#链接>"
</script>
<!--扩展设计器的样式-->
<link type='text/css' rel='stylesheet' href='../apps/com.actionsoft.apps.coe.pal/lib/designer/extend/css/designer.extend.css' />
<!--针对设计器进行颜色扩展,以及文字扩充-->
@ -190,6 +285,7 @@
<script src="../apps/com.actionsoft.apps.coe.pal/lib/designer/extend/js/driver.min.js"></script>
<script type="text/javascript">
//公共信息
var wsId = "<#wsId>";
var browserId = "<#browserId>";// 浏览器唯一标识
var appId = "<#appId>";
var sessionId = "<#sid>";
@ -601,11 +697,14 @@
function initContentHtml(obj){
var checkHtml = '';
obj.forEach(function(model, index) {
checkHtml += '<p>';
checkHtml += '<input class="awsui-checkbox" name="tplRadio" id="'+model.id+'" showText="'+model.text+'" type="radio"/>';
checkHtml += '<label class="awsui-checkbox-label">'+model.text+'</label>';
});
if (obj!=undefined) {
obj.forEach(function(model, index) {
checkHtml += '<p>';
checkHtml += '<input class="awsui-checkbox" name="tplRadio" id="'+model.id+'" showText="'+model.text+'" type="radio"/>';
checkHtml += '<label class="awsui-checkbox-label">'+model.text+'</label>';
});
}
return checkHtml;
}
@ -1009,9 +1108,12 @@
}
}*/
</script>
<!-- 版本对比 -->
<script type='text/javascript' async charset='UTF-8' src='../apps/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/versionCompare/version.methods.debug.js'></script>
</head>
<body style="overflow:hidden;" onload="updateShapePanel();">
<div class="compare-main" id="versionCompareBox" style="display:none;"></div>
<canvas id="support_canvas" style="display: none;"></canvas>
<div id="designer_header">
@ -1020,9 +1122,12 @@
<span class="diagram_title"><#fileName></span>
<span id="securityLevelName" style="display: none;"><#securityLevelName></span>
<div id="toolbar_wfversion_info" class="toolbar_info">
<div id="toolbar_designer_version_no" class="info version" awsui-qtip="版本管理">
<!-- <div id="toolbar_designer_version_no" class="info version" awsui-qtip="版本管理">
<#versionNum>
</div>
</div> -->
<span id="toolbar_designer_version_no" class="info version" style="cursor: pointer" awsui-qtip="版本号" onclick="versionListFun.openVersionList()">
<#versionNum>
</span>
<div id="toolbar_wfversion_info_status" style="display:none;" class="versioninfo version0" awsui-qtip="<#state>"><#state></div>
</div>
</div>

View File

@ -8,6 +8,7 @@
<link type='text/css' rel='stylesheet' href='../apps/com.actionsoft.apps.coe.pal/lib/designer/themes/default/global_zh.css' />
<link type='text/css' rel='stylesheet' href='../apps/com.actionsoft.apps.coe.pal/lib/designer/themes/default/diagraming/designer.css' />
<link type='text/css' rel='stylesheet' href='../apps/com.actionsoft.apps.coe.pal/lib/designer/themes/default/diagraming/ui.css' />
<link type='text/css' rel='stylesheet' href='../apps/com.actionsoft.apps.coe.pal/lib/designer/themes/default/diagraming/designer.versionCompare.css' />
<link rel="stylesheet" href="../commons/css/awsui.css">
<style>
.button.blue {
@ -93,6 +94,8 @@
<script type='text/javascript' src='../commons/js/public.js'></script>
<script type="text/javascript">
//公共信息
var wsId = "<#wsId>";
var teamId = "<#teamId>";
var browserId = "<#browserId>";// 浏览器唯一标识
var appId = "<#appId>";
var sessionId = "<#sid>";
@ -360,6 +363,102 @@
}
</script>
<!-- i18n -->
<script>
var 快速查询 = "<I18N#快速查询>";
var 已保存成功 = "<I18N#已保存成功>";
var 保存成功 = "<I18N#保存成功>";
var 页面中有未保存的内容请先保存 = "<I18N#页面中有未保存的内容请先保存>";
var 保存失败 = "<I18N#保存失败>";
var 列的第 = "<I18N#列的第>";
var 行不允许为空 = "<I18N#行不允许为空>";
var 文件属性 = "<I18N#文件属性>";
var 不允许为空 = "<I18N#不允许为空>";
var 返回 = "<I18N#返回>";
var 版本号 = "<I18N#版本号>";
var 吸色 = "<I18N#吸色>";
var 退出 = "<I18N#退出>";
var 当前颜色 = "<I18N#当前颜色>";
$(document).ready(function(){
$("#queryInput").attr("placeholder", 快速查询);
$("#back-vue-page-span").attr("awsui-qtip", 返回);
$("#toolbar_designer_version_no").attr("awsui-qtip", 版本号);
$("#color_draw").attr("awsui-qtip", 吸色 + "Esc" + 退出);
$("#color_show_now").attr("awsui-qtip", 当前颜色);
});
// designer.ui.debug.js i18n
var 颜色渐变 = "<I18N#颜色渐变>";
var 起始版本 = "<I18N#起始版本>";
var 错误个数 = "<I18N#错误个数>";
var 校验通过 = "<I18N#校验通过>";
var 文件过大不允许超过 = "<I18N#文件过大, 不允许超过>";
var 上传成功 = "<I18N#上传成功>";
var 正在加载预览 = "<I18N#正在加载预览>";
var 此地址下无法加载图片 = "<I18N#此地址下无法加载图片>";
var 请检查图片地址是否正确 = "<I18N#请检查图片地址是否正确>";
var 确保图片地址处于公开状态 = "<I18N#确保图片地址处于公开状态>";
var 正在加载图片 = "<I18N#正在加载图片>";
var 显示更多结果 = "<I18N#显示更多结果>";
var 正在应用图片请稍候 = "<I18N#正在应用图片请稍候>";
var 无法使用此图片请选择其他图片 = "<I18N#无法使用此图片请选择其他图片>";
var 页面中有未保存的内容请先保存 = "<I18N#页面中有未保存的内容请先保存>";
var 请稍后 = "<I18N#请稍后>";
var 请您先保存一个版本 = "<I18N#请您先保存一个版本>";
var 预览 = "<I18N#预览>";
var 图片创建完成 = "<I18N#图片创建完成>";
var 是否打开图片预览 = "<I18N#是否打开图片预览>";
var 导出完成 = "<I18N#导出完成>";
var 确定 = "<I18N#确定>";
var 关闭 = "<I18N#关闭>";
var 节点编号排序 = "<I18N#节点编号排序>";
var 提示 = "<I18N#提示>";
var 拖动排序确定后请保存设计器 = "<I18N#拖动排序确定后请保存设计器>";
var 无名称 = "<I18N#无名称>";
var 不支持编号排序 = "<I18N#不支持编号排序>";
var 画布没有形状或者形状没有编号属性 = "<I18N#画布没有形状或者形状没有编号属性>";
var 名称 = "<I18N#名称>";
var 节点号 = "<I18N#节点号>";
var 新发布 = "<I18N#新发布>";
var 变更 = "<I18N#变更>";
var 停用 = "<I18N#停用>";
var 暂无发布历史 = "<I18N#暂无发布历史>";
var 文件链接 = "<I18N#文件链接>";
var 自定义链接 = "<I18N#自定义链接>";
var 暂无链接 = "<I18N#暂无链接>";
var 处修改 = "<I18N#处修改>";
var 暂停 = "<I18N#暂停>";
var 从此版本播放 = "<I18N#从此版本播放>";
var 浏览器限制无法进入演示视图 = "<I18N#浏览器限制无法进入演示视图>";
var 无法进入全屏视图您可以按F11进入 = "<I18N#无法进入全屏视图您可以按(F11)进入>";
var 秒后自动保存 = "<I18N#秒后自动保存>";
var 修改 = "<I18N#修改>"
var 由 = "<I18N#>"
var 创建 = "<I18N#创建>"
var 新建版本 = "<I18N#新建版本>"
var 版本对比 = "<I18N#版本对比>"
var 切换该版本 = "<I18N#切换该版本>"
var 设计中 = "<I18N#设计中>"
var 已发布 = "<I18N#已发布>"
var 已停用 = "<I18N#已停用>"
var 审核中 = "<I18N#审核中>"
var 设计 = "<I18N#设计>"
var 是否继续切换 = "<I18N#是否继续切换>"
var 历史版本 = "<I18N#历史版本>"
var 提示 = "<I18N#提示>"
var 确定将 = "<I18N#确定将>"
var 版本为模板创建新版本文件 = "<I18N#版本为模板创建新版本文件>"
var 历史版本为模板创建新版本文件 = "<I18N#历史版本为模板创建新版本文件>"
var 请选择版本号 = "<I18N#请选择版本号>"
var 文件修改未保存 = "<I18N#文件修改未保存>"
var 文件已修改未保存 = "<I18N#文件已修改未保存>"
var 附件 = "<I18N#附件>"
var 形状属性 = "<I18N#形状属性>"
var 链接 = "<I18N#链接>"
</script>
<!-- 版本对比 -->
<script type='text/javascript' async charset='UTF-8' src='../apps/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/versionCompare/version.methods.debug.js'></script>
</head>
<body style="overflow:hidden;">
@ -370,9 +469,12 @@
<#checkoutTip>
<span class="diagram_title"><#fileName></span>
<div id="toolbar_wfversion_info" class="toolbar_info">
<div id="toolbar_designer_version_no" class="info version" awsui-qtip="版本管理">
<!-- <div id="toolbar_designer_version_no" class="info version" awsui-qtip="版本管理">
<#versionNum>
</div>
</div> -->
<span id="toolbar_designer_version_no" class="info version" style="cursor: pointer" awsui-qtip="版本号" onclick="versionListFun.openVersionList()">
<#versionNum>
</span>
<div id="toolbar_wfversion_info_status" style="display:none;" class="versioninfo version0" awsui-qtip="<#state>"><#state></div>
</div>
</div>

View File

@ -1564,6 +1564,7 @@
<cmd-bean name="com.actionsoft.apps.coe.pal_processlevel_create_method_list">
<param name="category"/>
<param name="methodId"/>
<param name="fileId"/>
</cmd-bean>
<cmd-bean name="com.actionsoft.apps.coe.pal_processlevel_folder_create_save">
<param name="wsId"/>

View File

@ -0,0 +1,785 @@
/**
* 业务代码
*/
// main页面打开版本列表
const versionListFun = {
versionList: [],
historyList: [],
openVersionList() {
let page = $("#versionList")
if (page.length > 0) {
this.closeVersionList()
return
}
$(`<div id="versionList" class="versionList"></div>`).appendTo("#designer_header")
this.loadVersionList()
},
loadVersionList() {
function versionItem(item) {
return `
<div class="version-item">
<div class="version-content">
<div class="top-info">
<span class="left-span version-state-${item.versionStatus}">${item.versionNo} ${item.versionStatus1}</span>
<span style="font-size: 12px;display: inline-flex;align-items: center">${item.updateTime}<span class="update-user-name" awsui-qtip="${item.updateUser}">${item.updateUser}</span>${}</span>
</div>
<div class="bottom-info">
<span class="left-span">${item.createTime}</span>
<span style="display: inline-flex;align-items: center"> ${}<span class="create-user-name" awsui-qtip="${item.createUser}">${item.createUser}</span>${}</span>
</div>
</div>
<div class="version-icon">
${item.hasCreatePerm ? `<i class="awsui-iconfont" awsui-qtip="${新建版本}" onclick="versionListFun.createNewVersion(event,${JSON.stringify(item).replace(/\"/g, "'")})">&#xe840;</i>` : ''}
<i class="awsui-iconfont" style="margin: 0 13px;display: ${item.versionStatus === 'use' ? 'none' : ''}" awsui-qtip="${版本对比}" onclick="versionListFun.openComparePage(event,${JSON.stringify(item).replace(/\"/g, "'")})">&#xe7cd;</i>
<i class="awsui-iconfont" awsui-qtip="${切换该版本}" style="display: ${item.isHistory || item.versionStatus === 'use' ? 'none' : ''}" onclick="versionListFun.switchVersion(event,${JSON.stringify(item).replace(/\"/g, "'")})">&#xe839;</i>
<div class="select-version" id="select_${item.plId}"></div>
</div>
</div>
`
}
awsui.ajax.request({
url: './jd',
method: 'POST',
data: {
cmd: 'com.actionsoft.apps.coe.pal_pl_repository_designer_version_list',
sid: sid,
wsId: wsId,
teamId: teamId,
id: ruuid
},
ok: function (res) {
if (res.result === 'ok') {
const status = {
use: 设计中,
publish: 已发布,
stop: 已停用,
approval: 审核中,
designer: 设计
}
let versionList = res.data.versionList, historyList = res.data.historyList
versionList.forEach(item => {
item.versionStatus1 = status[item.versionStatus]
})
historyList.forEach(item => {
item.versionStatus1 = status[item.versionStatus]
})
versionListFun.versionList = [...versionList]
versionListFun.historyList = [...historyList]
let str = ''
versionList.forEach(item => {
str += versionItem(item)
})
if (historyList.length > 0) {
str += `<div class="history-title">${历史版本}</div>`
historyList.forEach(item => {
str += versionItem({...item, isHistory: true})
})
}
$("#versionList").empty()
$("#versionList").append(str)
}
}
})
},
closeVersionList() {
if ($("#versionList")) {
$("#versionList").remove()
}
},
// 创建新版本
createNewVersion(event, item) {
event.stopPropagation()
if (versionListFun.historyList.length > 0 && isBpmSupportMinor != 'true') { // 不支持小版本迭代
$.confirm({
title: 提示,
content: `${确定将} ${item.versionNo} ${item.isHistory ? 历史版本为模板创建新版本文件 : 版本为模板创建新版本文件}?`,
onConfirm: function () {
awsui.ajax.request({
url: './jd',
method: 'POST',
data: {
cmd: 'com.actionsoft.apps.coe.pal_pl_repository_designer_version_manager_create',
sid: sid,
wsId: wsId,
teamId: teamId,
id: item.plId,
isLargeIteration: true,
isHistory: item.isHistory || false
},
ok: function (res) {
if (res.result === 'ok') {
versionListFun.loadVersionList()
}
}
})
}
})
} else {
let {plId, versionNo} = item
let selectVersion = $("#select_" + plId)
if (selectVersion.is(":visible")) {
selectVersion.empty()
selectVersion.hide()
return
}
$(".select-version").hide()
selectVersion.show()
let smallVersionInteger = parseInt(versionNo.match(/\d+\.\d+/g)[0]); // 小版本整数位
let smallVersionDecimal; // 小版本小数位
let arr1 = []; // 大版本号
let arr2 = []; // 以当前版本为大版本的所有小版本
let largeVersion, smallVersion
let allVersion = versionListFun.versionList.concat(versionListFun.historyList).map(item => item.versionNo.match(/\d+\.\d+/g)[0].split('.'))
allVersion.forEach(item => {
arr1.push(parseInt(item[0]))
if (item[0] == smallVersionInteger) {
arr2.push(parseInt(item[1]))
}
})
smallVersionDecimal = Math.max(...arr2) + 1
largeVersion = 'v' + (Math.max(...arr1) + 1).toFixed(1)
if (item.isHistory) {
smallVersion = 'v' + Math.max(...arr1) + '.' + smallVersionDecimal
} else {
smallVersion = 'v' + smallVersionInteger + '.' + smallVersionDecimal
}
selectVersion.html(`
<div>${请选择版本号}:</div>
<div style="height: 25px;padding: 8px 0 4px 0;">
<input class="awsui-radio" type="radio" name="versionRadio" isLargeIteration="true">
<span style="line-height: 19px">${largeVersion}</span>
</div>
<div>
<input class="awsui-radio" type="radio" name="versionRadio" isLargeIteration="false">
<span style="line-height: 19px">${smallVersion}</span>
</div>
`)
$("input[name='versionRadio']").on("click", function (event) {
event.stopPropagation()
let isLargeIteration = $(this).attr("isLargeIteration") == 'true'
awsui.ajax.request({
url: './jd',
method: 'POST',
data: {
cmd: 'com.actionsoft.apps.coe.pal_pl_repository_designer_version_manager_create',
sid: sid,
wsId: wsId,
teamId: teamId,
id: item.plId,
isLargeIteration: isLargeIteration,
isHistory: item.isHistory || false
},
ok: function (res) {
if (res.result === 'ok') {
let newId = res.data.uuid
awsui.ajax.request({
url: './jd',
method: 'POST',
data: {
cmd: 'com.actionsoft.apps.coe.pal_pl_repository_designer_version_manager_use',
sid: sid,
wsId: wsId,
teamId: teamId,
id: newId,
},
ok: function (res) {
if (res.result === 'ok') {
let currentURL = window.location.href
let url = new URL(currentURL)
let searchParams = new URLSearchParams(url.search)
searchParams.set('uuid', newId);
url.search = searchParams.toString()
window.location.href = url.toString()
}
}
})
}
}
})
});
}
},
// 打开版本对比
openComparePage(event, item) {
event.stopPropagation()
let compareBox = $("#versionCompareBox")
compareBox.empty()
compareBox.show()
let str = '<iframe id="versionCompareContent" name="versionCompareContent" style="width: 100%; height: 100%;border: none"></iframe>';
compareBox.append(str);
$('#versionCompareContent').attr(
'src', "./w?sid=" + sid
+ "&cmd=com.actionsoft.apps.coe.pal_pl_repository_designer_version_compare"
+ "&wsId=" + wsId
+ "&compareVerId=" + item.plId
+ "&curId=" + ruuid
+ "&teamId=" + teamId
// 添加子页面所需参数:是否为历史版本
+ "&isHistory=" + item.isHistory
)
versionListFun.closeVersionList()
},
// 关闭版本对比
closeComparePage() {
parent.$("#versionCompareBox").hide()
parent.$("#versionCompareBox").empty()
},
// 切换版本
switchVersion(event, item) {
event.stopPropagation()
if ($("#saving_tip").text() == 文件已修改未保存) {
$.confirm({
title: 提示,
content: 文件修改未保存 + '' + 是否继续切换,
onConfirm: function () {
versionListFun.changeCurVersion(item.plId)
}
})
} else {
versionListFun.changeCurVersion(item.plId)
}
},
changeCurVersion(uuid) {
awsui.ajax.request({
url: './jd',
method: 'POST',
data: {
cmd: 'com.actionsoft.apps.coe.pal_pl_repository_designer_version_manager_use',
sid: sid,
wsId: wsId,
teamId: teamId,
id: uuid,
},
ok: function (res) {
if (res.result === 'ok') {
let currentURL = window.location.href
let url = new URL(currentURL)
let searchParams = new URLSearchParams(url.search)
searchParams.set('uuid', uuid);
url.search = searchParams.toString()
window.location.href = url.toString()
}
}
})
}
}
// 版本对比页面
const designerZoomYl = {
left: 100,
right: 100
}
const fileTabStr = ` <div class="attr-tab active-tab" tab="attr">
<div class="tab-name">${文件属性}</div>
</div>
<div class="attr-tab" tab="upFile">
<div class="tab-name">${附件}</div>
</div>
`
const shapeTabStr = ` <div class="attr-tab active-tab" tab="attr">
<div class="tab-name">${形状属性}</div>
</div>
<div class="attr-tab" tab="upFile">
<div class="tab-name">${附件}</div>
</div>
<div class="attr-tab" tab="link">
<div class="tab-name">${链接}</div>
</div>
`
const versionCompareFun = {
// 缩放
pageZoom(position, type) {
function handleZoom(position, type) {
if (type == 'zoomIn') {
if (designerZoomYl[position] + 10 > 200) {
designerZoomYl[position] = 200;
} else {
designerZoomYl[position] = designerZoomYl[position] + 10;
}
} else if (type == 'zoomOut') {
if (designerZoomYl[position] - 10 < 50) {
designerZoomYl[position] = 50;
} else {
designerZoomYl[position] = designerZoomYl[position] - 10;
}
} else {
designerZoomYl[position] = 100;
}
VersionDesigner.setZoomScale(position, designerZoomYl[position] / 100);
$("#zoom-value-" + position).text(Math.round(VersionDesigner.config.scale[position] * 100) + '%')
}
handleZoom(position, type)
if (isSameOperate) {
let otherPos = position === "left" ? "right" : "left";
designerZoomYl[otherPos] = designerZoomYl[position]
VersionDesigner.setZoomScale(otherPos, designerZoomYl[position] / 100);
$("#zoom-value-" + otherPos).text(Math.round(VersionDesigner.config.scale[otherPos] * 100) + '%')
}
},
// 鹰眼导航
openNavigation: function (position, isShow) {
function handleNav(position, isShow) {
if (isShow) {
$("#navigation-view-" + position).show()
Navigator.draw(position)
$('#show-nav-' + position).hide()
$('#close-nav-' + position).show()
} else {
$("#navigation-view-" + position).hide()
$('#show-nav-' + position).show()
$('#close-nav-' + position).hide()
}
}
handleNav(position, isShow)
if (isSameOperate) {
let otherPos = position === "left" ? "right" : "left";
handleNav(otherPos, isShow)
}
},
openAttributeView: function (position) {
function handleAttrView(position) {
let selectedLength = Utils.getSelected(position).length
let view = $("#attribute-view-" + position)
let headLeft = view.find('.head-left')
if (selectedLength > 0) {
headLeft.attr('viewType', 'shape')
headLeft.html(shapeTabStr)
versionCompareFun.writeShapeAttributeHtml(position)
} else {
headLeft.attr('viewType', 'file')
headLeft.html(fileTabStr)
versionCompareFun.writeFileAttributeHtml(position)
}
view.show()
let btn = $("#view-btn-" + position)
btn.find('.btn-text').remove()
btn.css('width', '45px')
btn.hide()
versionCompareFun.attrViewEvent(position)
}
handleAttrView(position)
if (isSameOperate) {
let otherPos = position === "left" ? "right" : "left";
handleAttrView(otherPos)
}
},
closeAttributeView: function (position) {
$("#attribute-view-" + position).hide()
$("#view-btn-" + position).show()
if (isSameOperate) {
let otherPos = position === "left" ? "right" : "left";
$("#attribute-view-" + otherPos).hide()
$("#view-btn-" + otherPos).show()
}
},
// view事件
attrViewEvent: function (position) {
let otherPos = position === "left" ? "right" : "left";
let view = $("#attribute-view-" + position), viewBody = $("#view-body-" + position)
let otherView = $("#attribute-view-" + otherPos)
// tab点击
view.find(".head-left").off("click").on("click", ".attr-tab", function () {
view.find(".head-left div.active-tab").removeClass("active-tab");
$(this).addClass("active-tab");
let activeTab = $(this).attr("tab")
viewBody.children().css('display', 'none')
viewBody.find('.view-' + activeTab).show()
if (isSameOperate) {
if (otherView.is(":visible")) {
let curType = $(this).parent().attr("viewType") // 当前是文件属性还是数据属性 file/shape
let otherViewHead = otherView.find('.head-left'), otherViewBody = $("#view-body-" + otherPos), otherType = otherViewHead.attr("viewType")
if (curType === otherType) {
updateActiveTab(otherViewHead, otherViewBody, activeTab)
} else {
if (curType === 'shape') {
let selectedId = Utils.getSelectedIds(position)[0]
if (PageModel[otherPos].define.elements[selectedId]) {
Utils.selectShape(otherPos, selectedId)
versionCompareFun.updateAttributeView(otherPos)
updateActiveTab(otherViewHead, otherViewBody, activeTab)
}
} else {
Utils.unselect(otherPos)
versionCompareFun.updateAttributeView(otherPos)
updateActiveTab(otherViewHead, otherViewBody, activeTab)
}
}
}
}
function updateActiveTab(otherViewHead, otherViewBody, activeTab) {
otherViewHead.children().removeClass("active-tab")
otherViewHead.find(`div[tab=${activeTab}]`).addClass("active-tab")
otherViewBody.children().css('display', 'none')
otherViewBody.find('.view-' + activeTab).show()
}
})
// 内容滚动
viewBody.off("scroll").on("scroll", function () {
if (isSameOperate) {
if (otherView.is(":visible")) {
let otherViewBody = $("#view-body-" + otherPos)
otherViewBody.scrollTop($(this).scrollTop())
}
}
})
},
// 点击画布更新属性页面
updateAttributeView: function (position) {
let view = $("#attribute-view-" + position)
let headLeft = view.find('.head-left')
let viewType = headLeft.attr('viewType') // 当前是文件属性还是数据属性 file/shape
if (view.is(":visible")) {
let selectedLength = Utils.getSelected(position).length
if (viewType === 'file') { // 已经打开了文件属性窗口
if (selectedLength > 0) {
headLeft.html(shapeTabStr)
headLeft.attr('viewType', 'shape')
this.writeShapeAttributeHtml(position)
}
} else { // 已经打开了数据属性窗口
if (selectedLength > 0) {
this.writeShapeAttributeHtml(position)
} else {
headLeft.html(fileTabStr)
headLeft.attr('viewType', 'file')
this.writeFileAttributeHtml(position)
}
}
this.attrViewEvent(position)
}
},
// 文件属性
writeFileAttributeHtml: function (position) {
const view = $("#attribute-view-" + position)
const activeTab = view.find(".active-tab").attr("tab")
let body = $("#view-body-" + position)
body.empty()
let allData = position === 'left' ? versionData : curData
let attr = allData.fileAttr, upFile = allData.fileUpFile, relationUpFile = allData.fileRelationUpFile
let attrStr = this.getAttrStr(position, attr)
let bodyStr = `<div class="view-attr" style="display:none;">
${attrStr === '' ? `<div class="category-item">${暂无文件属性}</div>` : `${attrStr}`}
</div>
<div class="view-upFile" style="display:none;">
${this.getAttrStr(position, [{type: 'file', name: 附件, value: upFile.value, isDiff: upFile.isDiff,}])}
${this.getAttrStr(position, [{type: 'file', name: 关联附件, value: relationUpFile.value, isDiff: relationUpFile.isDiff}])}
</div>`
body.html(bodyStr)
body.find('.view-' + activeTab).show()
// 追加差异样式
view.find(".tab-name").removeClass('attr-diff')
if (attr && attr.some(i => i.isDiff)) {
view.find('div[tab=attr]').find('.tab-name').addClass('attr-diff')
}
},
// 形状属性
writeShapeAttributeHtml: function (position) {
const view = $("#attribute-view-" + position)
const activeTab = view.find(".active-tab").attr("tab")
let body = $("#view-body-" + position)
body.empty()
let shape = Utils.getSelected(position)[0]
const allData = position === 'left' ? versionData : curData
let attributeArr = allData.shapeAttr[shape.id] || [],
shapeUpFile = allData.shapeUpFile[shape.id] || {},
shapeRelationUpFile = allData.shapeRelationUpFile[shape.id] || {},
shapeLink = allData.shapeLink[shape.id] || {file: {}, custom: {}}
let attrStr = this.getAttrStr(position, attributeArr)
let bodyStr = `<div class="view-attr" style="display:none;">
${attrStr === '' ? `<div class="category-item">${暂无形状属性}</div>` : `${attrStr}`}
</div>
<div class="view-upFile" style="display:none;">
${this.getAttrStr(position, [{type: 'file', name: 附件, value: shapeUpFile.value, isDiff: shapeUpFile.isDiff,}])}
${this.getAttrStr(position, [{type: 'file', name: 关联附件, value: shapeRelationUpFile.value, isDiff: shapeRelationUpFile.isDiff}])}
</div>
<div class="view-link" style="display:none;">
${this.getAttrStr(position, [{type: 'shapeLink', name: 文件链接, value: shapeLink.file.value, isDiff: shapeLink.file.isDiff}])}
${this.getAttrStr(position, [{type: 'shapeLink', name: 自定义链接, value: shapeLink.custom.value, isDiff: shapeLink.custom.isDiff}])}
</div>`
body.html(bodyStr)
body.find('.view-' + activeTab).show()
// 追加差异样式
view.find(".tab-name").removeClass('attr-diff')
if (attributeArr.some(i => i.isDiff)) {
view.find('div[tab=attr]').find('.tab-name').addClass('attr-diff')
}
if (shapeUpFile.isDiff || shapeRelationUpFile.isDiff) {
view.find('div[tab=upFile]').find('.tab-name').addClass('attr-diff')
}
if (shapeLink.file.isDiff || shapeLink.custom.isDiff) {
view.find('div[tab=link]').find('.tab-name').addClass('attr-diff')
}
},
getAttrStr: function (position, attr) {
let str = ''
if (!attr) return str;
attr.forEach(item => {
if (item.type === 'relation' || item.type === 'awsorg') {
item.value = item.value.toString()
}
let contentStr = ''
switch (item.type) {
case 'table':
if (item.value) {
let tableStr = ''
let table = JSON.parse(item.value).table
let t1 = table[0].name, t2 = table[0].desc
tableStr += `<div class="table-header">
<div class="left-tr" >${t1}</div>
<div class="right-tr">${t2}</div>
</div>`
for (let i = 1; i < table.length; i++) {
let t1 = table[i].name, t2 = table[i].desc
tableStr += `<div class="table-row">
<div class="left-tr">${t1}</div>
<div class="right-tr">${t2}</div>
</div>`
}
contentStr = `<div class="attr-table-content">${tableStr}</div>`
} else {
contentStr = `<div class="category-content">${暂无}${item.name}</div>`
}
break;
case 'file':
let isHighSecurity = false
let fileList = item.value || []
let listStr = ''
fileList.forEach(item => {
let security = '' // 三元
if (isHighSecurity) {
security = `<span style="color: ${item.securityInfo.color}">${item.securityInfo.name}</span>`
}
listStr += `<div class="file-item">
<div class="name-box">
<span class="name-content" awsui-qtip="${item.fileName}" style="max-width: ${security === '' ? '100%' : 'calc(100% - 50px)'}" >${item.fileName}</span>
${security}
</div>
<div class="file-menu" awsui-qtip="${预览}" onclick="versionCompareFun.previewFile('${position}',${JSON.stringify(item).replace(/\"/g, "'")})">
<i class="awsui-iconfont">&#xe698;</i>
</div>
</div>`
})
contentStr = `<div class="category-content">${listStr === '' ? `${暂无}${item.name}` : listStr}</div>`
break;
case 'link':
contentStr = `<div class="category-content">
${item.value === '' ? `${暂无}${item.name}` : `<a href="${item.value}" target="_blank" style="color: #333">${item.value}</a>`}
</div>`
break;
case 'shapeLink':
let linkStr = '', list = item.value || []
list.forEach(i => {
linkStr += `<div class="file-item">
<div class="name-box" awsui-qtip="${i.url}">
<a href="${i.url}" target="_blank" style="color: #333">${i.value}</a>
</div>
</div>`
})
contentStr = `<div class="category-content">${linkStr === '' ? `${暂无}${item.name}` : linkStr}</div>`
break;
default:
contentStr = `<div class="category-content">
${item.value === '' ? `${暂无}${item.name}` : `${item.value}`}
</div>`
}
str += `<div class="category-item ${item.isDiff ? 'attr-diff' : ''}">
<div class="attr-title">${item.name}</div>
${contentStr}
</div>`
})
return str
},
// 预览
previewFile(position, file) {
const imgType = ['jpg', 'jpeg', 'gif', 'png']
const fileType = file.fileName.split('.').reverse()[0]
if (!imgType.includes(fileType)) { // 不是图片
window.open(file.downloadUrl)
return
}
$("#attribute-view-" + position).css('opacity', 0)
$('#model-' + position).show()
const otherPos = position === 'left' ? 'right' : 'left'
const windowWidth = document.body.clientWidth
const dialog = $('#file-preview-' + position), otherDialog = $('#file-preview-' + otherPos)
const img = new Image()
img.src = file.downloadUrl
img.addEventListener('load', function () {
dialog.find('img').attr('src', img.src)
dialog.dialog({
title: file.fileName,
width: 650,
height: 480,
model: false,
onClose: function () {
$('#model-' + position).hide()
$("#attribute-view-" + position).css('opacity', 1)
}
})
let dialogWidth = dialog.outerWidth(true), otherDialogWidth = otherDialog.outerWidth(true)
let x = windowWidth / 2 / 2 - dialogWidth / 2
if (position === 'right') {
x += windowWidth / 2
}
dialog.css({
left: x + 'px'
})
if (otherDialog.is(":visible")) {
// dialog机制会把已经打开的dialog居中 这里重新设置一下
let x = windowWidth / 2 / 2 - otherDialogWidth / 2
if (otherPos === 'right') {
x += windowWidth / 2
}
otherDialog.css({
left: x + 'px'
})
}
})
},
// 同步操作
isOpenSameOperate(isOpen) {
isSameOperate = isOpen
if (isOpen) {
$('.opend-operate').show()
$('.closed-operate').hide()
} else {
$('.opend-operate').hide()
$('.closed-operate').show()
}
},
// 版本列表
openCompareList() {
versionCompareFun.closeAttributeView('left')
versionCompareFun.closeAttributeView('right')
let page = $("#compareVersionList")
if (page.is(":visible")) {
page.hide()
page.empty()
} else {
awsui.ajax.request({
url: './jd',
method: 'POST',
data: {
cmd: 'com.actionsoft.apps.coe.pal_pl_repository_designer_version_list',
sid: parent.sid,
wsId: parent.wsId,
teamId: parent.teamId,
id: parent.ruuid
},
ok: function (res) {
if (res.result === 'ok') {
const status = {
use: 设计中,
publish: 已发布,
stop: 已停用,
approval: 审核中,
designer: 设计
}
let versionList = res.data.versionList, historyList = res.data.historyList
versionList.forEach(item => {
item.versionStatus1 = status[item.versionStatus]
})
historyList.forEach(item => {
item.isHistory = true
item.versionStatus1 = status[item.versionStatus]
})
let allList = versionList.concat(historyList)
page.empty()
let str = ''
allList.forEach(item => {
let isDisabled = item.versionNo === versionData.versionNo || item.versionNo === curData.versionNo
str += `
<div style="cursor: ${isDisabled ? 'not-allowed' : 'pointer'}" class="version-item ${isDisabled ? 'disabled' : ''}" onclick="versionCompareFun.changeComparePageUrl(this,'${item.plId}','${item.isHistory}')">
<div class="version-content">
<div class="top-info">
<span class="left-span version-state-${item.versionStatus}">${item.versionNo} ${item.versionStatus1}</span>
</div>
<div class="bottom-info">
<span style="display: inline-flex;align-items: center">${item.updateTime} ${}<span style="max-width: 65px" class="update-user-name" awsui-qtip="${item.updateUser}">${item.updateUser}</span>${}</span>
</div>
</div>
<div style="width: 30px;text-align: center">
<i class="awsui-iconfont" style="font-size: 20px">${item.versionNo === versionData.versionNo ? '&#xea2e;' : ''}</i>
</div>
</div>
`
})
page.append(str)
page.show()
}
}
})
}
},
// 点击监听 关闭版本列表
closeVersionListByClick(event) {
let page = $("#compareVersionList")
if (!page.is(":visible")) {
return;
}
let targetElement = event.target; // 获取被点击的元素
let isClickInsideDropdown = document.getElementById('compareVersionList').contains(targetElement); // 检查点击是否在下拉框内
let isClickOnButton = document.querySelector('.center-top').contains(targetElement); // 检查点击是否在触发按钮内
if (!isClickInsideDropdown && !isClickOnButton) {
// 关闭下拉框
page.hide()
page.empty()
}
},
// 切换对比版本
changeComparePageUrl($this, compareVerId, isHistory) {
if ($($this).hasClass('disabled')) return
let listBox = $("#compareVersionList"), iframe = parent.$('#versionCompareContent')
listBox.hide()
listBox.empty()
parent.$.simpleAlert(正在切换, 'loading')
iframe.attr(
'src', "./w?sid=" + parent.sid
+ "&cmd=com.actionsoft.apps.coe.pal_pl_repository_designer_version_compare"
+ "&wsId=" + parent.wsId
+ "&compareVerId=" + compareVerId
+ "&curId=" + curData.plId
+ "&teamId=" + parent.teamId
// 添加子页面所需参数:是否为历史版本
+ "&isHistory=" + isHistory
)
iframe.on('load', function () {
parent.$.simpleAlert("close")
})
},
// 切换到该版本
changeToSelectedV() {
$.confirm({
title: 提示,
content: 是否将 + ` ${versionData.versionNo} ` + 切换为使用中,
onConfirm: function () {
awsui.ajax.request({
url: './jd',
method: 'POST',
data: {
cmd: 'com.actionsoft.apps.coe.pal_pl_repository_designer_version_manager_use',
sid: parent.sid,
wsId: parent.wsId,
teamId: parent.teamId,
id: versionData.plId,
},
ok: function (res) {
if (res.result === 'ok') {
let currentURL = parent.window.location.href
let url = new URL(currentURL)
let searchParams = new URLSearchParams(url.search)
searchParams.set('uuid', versionData.plId);
url.search = searchParams.toString()
parent.window.location.href = url.toString()
}
}
})
}
})
}
}

View File

@ -0,0 +1,643 @@
.compare-main {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 9999
}
.versionList {
position: absolute;
top: 45px;
right: 75px;
width: 430px;
height: 310px;
padding: 10px;
overflow: auto;
background: #fff;
box-shadow: 0px 6px 18px 0px rgba(0, 21, 44, 0.1);
border-radius: 8px;
z-index: 9999;
}
.compare-version-list {
position: absolute;
top: 40px;
left: -131px;
width: 290px;
height: 310px;
padding: 10px;
overflow: auto;
background: #fff;
box-shadow: 0px 6px 18px 0px rgba(0, 21, 44, 0.1);
border-radius: 8px;
z-index: 9999;
}
.version-item {
height: 60px;
margin-bottom: 2px;
border-radius: 4px;
display: flex;
align-items: center;
padding: 0 14px 0 18px
}
.disabled {
background: #f2f2f2 !important;
color: #c0c4cc;
cursor: not-allowed;
}
.version-state-use {
color: #4E7FF9
}
.version-state-publish {
color: #1FDD00
}
.version-state-stop {
color: #E02020
}
.version-state-approval {
color: #FF8F0B
}
.version-state-designer {
color: #8592A6
}
.version-item:hover {
background: #F1F6FF;
}
.version-item:hover .version-icon {
visibility: visible;
}
.version-content {
flex: 1
}
.version-content .left-span {
display: inline-block;
width: 90px;
}
.version-content .top-info {
font-size: 14px;
padding: 3px 0;
}
.version-content .bottom-info {
color: #8592A6;
font-size: 12px;
}
.version-content .update-user-name {
display: inline-block;
max-width: 80px;
padding: 0 5px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.version-content .create-user-name {
display: inline-block;
max-width: 150px;
padding: 0 5px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.version-icon {
position: relative;
width: 85px;
visibility: hidden;
}
.version-icon i {
font-size: 17px;
cursor: pointer;
color: #8592A6;
}
.select-version {
display: none;
position: absolute;
top: 23px;
left: -110px;
width: 140px;
height: 100px;
font-size: 14px;
background: #FFFFFF;
box-shadow: 0px 4px 12px 0px rgba(0, 0, 0, 0.1);
border-radius: 4px;
padding: 10px 15px;
box-sizing: border-box;
z-index: 1;
}
.history-title {
border-top: 1px solid #D9D9D9;
margin-top: 5px;
font-weight: 500;
font-size: 14px;
color: #333333;
padding: 12px 0 12px 20px;
}
/********************************** 下面是版本对比页面 ******************************************************/
.flex-center {
display: flex;
align-items: center;
justify-content: space-between
}
.page-head {
height: 60px;
padding: 0 10px;
}
.left,
.right {
flex: 1;
display: flex;
}
.page-head .method-icon {
display: inline-block;
color: white;
width: 30px;
height: 30px;
margin: 0 10px;
border-radius: 3px;
text-align: center;
line-height: 30px;
}
.page-head .left-right {
min-width: 90px;
padding: 0 5px;
height: 34px;
line-height: 34px;
background: #FFFFFF;
border-radius: 4px 4px 4px 4px;
border: 1px solid #DDDDDD;
text-align: center;
margin-right: 15px;
cursor: pointer;
}
.page-head .left-center {
height: 40px;
width: 100px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
}
.page-head .update-time {
font-size: 12px;
color: #8592A6;
}
.center-top {
font-size: 14px;
cursor: pointer;
}
.same-operate {
width: 26px;
height: 26px;
line-height: 26px;
border-radius: 2px;
color: #fff;
text-align: center;
cursor: pointer;
box-shadow: 5px -5px 0px 0px #83AEFF;
}
.opend-operate {
background: #2978FF;
box-shadow: 5px -5px 0px 0px #83AEFF;
}
.closed-operate {
background: #5B606A;
box-shadow: 5px -5px 0px 0px #A0AAB5;
}
.designer-wrapper {
position: relative;
width: 50%;
height: calc(100vh - 60px - 35px);
border-top: 1px solid #666;
}
.version-designer-layout {
width: 100%;
height: 100%;
background: url(../images/diagraming/canvas_bg.jpg) repeat;
overflow: auto;
}
.version-canvas_container {
padding: 10px;
}
.version-canvas {
position: relative;
background: #fff;
width: 100%;
height: 100%;
cursor: default;
}
.version-footer {
height: 35px;
display: flex;
}
.footer-half {
position: relative;
height: 100%;
width: 50%;
display: flex;
align-items: center;
justify-content: flex-end;
}
.footer-half .zoom-value {
display: inline-block;
font-size: 14px;
width: 50px;
text-align: center;
cursor: pointer;
}
.footer-half i {
cursor: pointer;
margin: 0 10px;
user-select: none;
}
.shape_box {
position: absolute;
}
.text_canvas {
position: absolute;
padding: 0px;
border: none;
background: transparent;
cursor: inherit;
overflow: hidden;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}
.attr_canvas {
position: absolute;
}
input,
textarea {
resize: none;
outline: none;
font-size: 13px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.shape-controls {
position: absolute;
}
.shape-controls .controls-bounding {
position: absolute;
left: -10px;
top: -10px;
}
.shape_controller {
position: absolute;
border-style: solid;
border-width: 1px;
background: white;
}
.shape_locker {
position: absolute;
}
.diff-icon-wrapper {
position: absolute;
left: 0;
top: -23px;
z-index: 200;
}
.diff-icon-span {
display: inline-block;
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
text-align: center;
margin-right: 4px;
}
.diff-icon-span i {
color: #fff;
font-size: 14px;
}
.shape_link_point {
cursor: pointer;
position: absolute;
right: -14px;
bottom: -0px;
width: 10px;
height: 10px;
color: #515151;
}
.shape_attachment_point {
cursor: pointer;
position: absolute;
right: -14px;
bottom: 16px;
width: 10px;
height: 10px;
}
/********************************** 鹰眼视图开始 ***************************************/
.version-dock_view {
display: none;
position: absolute;
top: -200px;
right: 20px;
width: 220px;
background: #f5f5f5;
border: 1px solid #999;
-webkit-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.33);
-moz-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.33);
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.33);
}
.navigation_bounding {
padding: 10px 0px;
overflow: hidden;
}
.navigation_view_container {
margin: 0px auto;
position: relative;
width: 120px;
}
.navigation_canvas {
background: white;
border: 1px solid #888;
}
.navigation_eye {
position: absolute;
border: 2px solid #6EB1EB;
top: 0px;
left: 0px;
width: 100px;
height: 80px;
}
/********************************** 鹰眼视图结束 ***************************************/
.attribute-view {
display: none;
position: absolute;
right: 2px;
top: 2px;
height: calc(100% - 4px);
width: 390px;
background: #FFFFFF;
box-shadow: -6px 0px 18px 0px rgba(0, 0, 0, 0.1);
z-index: 299;
}
.attribute-view-btn {
position: absolute;
right: 0;
top: 30px;
width: 40px;
height: 40px;
background: #FFFFFF;
box-shadow: 0 2px 10px 0 rgba(227, 233, 241, 0.7);
border-radius: 25px 0 0 25px;
border: 1px solid #DFE5F0;
padding: 0 5px 0 8px;
box-sizing: border-box;
display: flex;
align-items: center;
cursor: pointer;
/*transition: width .1s ease-in-out;*/
user-select: none;
z-index: 299;
}
.attribute-view-btn .btn-icon {
width: 32px;
height: 32px;
line-height: 32px;
text-align: center;
pointer-events: none;
}
.attribute-view .view-head {
display: flex;
align-items: center;
justify-content: space-between;
height: 54px;
padding: 0 16px;
border-bottom: 1px solid #DFE5F0;
font-size: 14px;
font-weight: 500;
}
.view-head .head-left {
height: 100%;
display: flex;
align-items: center;
}
.attr-tab {
height: 100%;
display: flex;
align-items: center;
margin-right: 15px;
border-bottom: solid 2px transparent;
}
.attr-tab .tab-name {
padding: 3px;
cursor: pointer;
}
.head-right i {
cursor: pointer;
font-size: 12px;
color: #4C576C;
}
.active-tab {
cursor: default;
border-bottom: solid 2px #4e7ff9;
color: #4e7ff9;
}
.attribute-view .view-body {
box-sizing: border-box;
padding: 8px;
height: calc(100% - 54px);
overflow: auto;
}
.category-item {
padding: 8px;
margin-bottom: 2px;
}
.attr-diff {
background: rgba(255, 143, 11, 0.15);
border: 2px dashed #FF8F0B;
}
.category-item .attr-title {
font-weight: 500;
font-size: 14px;
color: #333333;
margin-bottom: 10px;
}
.category-item .category-content {
background: #F5F5F5;
border-radius: 4px;
padding: 5px 10px;
min-height: 15px;
}
.attr-table-content {
border-radius: 4px 4px 0 0;
border: 1px solid #D9D9D9;
}
.attr-table-content .table-header {
display: flex;
height: 32px;
line-height: 32px;
background: #F5F5F5;
border-radius: 4px 4px 0 0;
border-bottom: 1px solid #D9D9D9;
}
.table-header div {
text-align: center;
}
.attr-table-content .table-row {
display: flex;
border-bottom: 1px solid #D9D9D9;
}
.category-item .table-row:last-child {
border-bottom: none;
}
.table-row div {
padding: 6px 5px;
}
.attr-table-content .left-tr {
box-sizing: border-box;
width: 110px;
border-right: 1px solid #D9D9D9;
}
.attr-table-content .right-tr {
flex: 1;
}
.file-item {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
}
.name-box {
width: calc(100% - 30px);
display: flex;
align-items: center;
}
.name-box .name-content {
display: inline-block;
max-width: calc(100% - 30px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.file-item .file-menu {
visibility: hidden;
}
.file-item:hover .file-menu {
cursor: pointer;
visibility: visible;
}
.dialog-model {
position: absolute;
top: 60px;
width: 50%;
height: calc(100% - 60px);
background: #fff;
z-index: 299;
opacity: 0.6;
}
.shape-tip {
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 299;
color: #E02020;
writing-mode: vertical-rl;
text-align: center;
padding: 35px 6px;
background: #FFFCFC;
letter-spacing: 3px;
display: none;
}
.shape-tip-left {
right: 0;
clip-path: polygon(0 30px, 100% 0, 100% 100%, 0 calc(100% - 30px));
}
.shape-tip-right {
left: 0;
clip-path: polygon(0 0, 100% 30px, 100% calc(100% - 30px), 0 100%);
}

View File

@ -0,0 +1,27 @@
package com.awspaas.user.apps.coe.method.process.freedom.listener;
import com.actionsoft.apps.coe.pal.pal.method.extend.MethodAppManager;
import com.actionsoft.apps.listener.AppListener;
import com.actionsoft.apps.resource.AppContext;
/**
* Created with IntelliJ IDEA.
*
* @Author: yuandongqiang
* @Date: 2025/6/4
* @Description:
*/
public class StartListener implements AppListener {
@Override
public boolean before(AppContext appContext) {
return true;
}
@Override
public void after(AppContext appContext) {
this.initMethod(appContext);
}
private void initMethod(AppContext appContext){
MethodAppManager.register("freedom.allmethod", appContext, "freedom.allmethod", "自由流程建模方法");
}
}

View File

@ -0,0 +1,34 @@
package com.awspaas.user.apps.coe.method.process.freedom.plugin;
import com.actionsoft.apps.listener.PluginListener;
import com.actionsoft.apps.resource.AppContext;
import com.actionsoft.apps.resource.plugin.profile.AWSPluginProfile;
import com.actionsoft.apps.resource.plugin.profile.AppExtensionProfile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created with IntelliJ IDEA.
*
* @Author: yuandongqiang
* @Date: 2025/6/4
* @Description: 插件
*/
public class Plugins implements PluginListener {
@Override
public List<AWSPluginProfile> register(AppContext appContext) {
List<AWSPluginProfile> list = new ArrayList<AWSPluginProfile>();
// PAL应用扩展点
Map<String, Object> params1 = new HashMap<String, Object>();
params1.put("title", "自由模型建模方法");
params1.put("icon", "");
params1.put("desc", "自由模型建模方法");
params1.put("methodId", "freedom.allmethod");
params1.put("deletedClass", "");
list.add(new AppExtensionProfile("PAL流程资产库->自由模型建模方法", "aslp://com.actionsoft.apps.coe.pal/registerMethodApp", params1));
return list;
}
}