diff --git a/com.actionsoft.apps.coe.pal/i18n/resource.xml b/com.actionsoft.apps.coe.pal/i18n/resource.xml index 33976180..cfa93983 100755 --- a/com.actionsoft.apps.coe.pal/i18n/resource.xml +++ b/com.actionsoft.apps.coe.pal/i18n/resource.xml @@ -116,7 +116,12 @@ - + + + + + + diff --git a/com.actionsoft.apps.coe.pal/manifest.xml b/com.actionsoft.apps.coe.pal/manifest.xml index b9a5c7aa..56387d96 100755 --- a/com.actionsoft.apps.coe.pal/manifest.xml +++ b/com.actionsoft.apps.coe.pal/manifest.xml @@ -85,6 +85,7 @@ AWS PAL(Process Asset Library)流程资产库是AWS CoE平台的重要产品组 [{"name":"建模操作快速引导","url":"","children":[{"name":"1.如何创建符号与连线","url":"./w?sid=@sid&cmd=com.actionsoft.apps.cms_get_message&messageId=e0606a45-56d3-4cff-b51f-e0a9d64e522a"},{"name":"2.快速调整布局","url":"./w?sid=@sid&cmd=com.actionsoft.apps.cms_get_message&messageId=6e58d212-fb95-4483-93b7-17499d632805"},{"name":"3.术语的新建与删除","url":"./w?sid=@sid&cmd=com.actionsoft.apps.cms_get_message&messageId=e5ef6605-3bc0-44b9-8bb8-a252fe20837b"},{"name":"4.流程绩效指标的新建与修改","url":"./w?sid=@sid&cmd=com.actionsoft.apps.cms_get_message&messageId=59b638b6-7e3a-4a79-bd71-cd739259c89d"},{"name":"5.新建表单模型","url":"./w?sid=@sid&cmd=com.actionsoft.apps.cms_get_message&messageId=0b964b9e-6701-44a8-8159-91b4ceba9c80"},{"name":"6.新建制度模型","url":"./w?sid=@sid&cmd=com.actionsoft.apps.cms_get_message&messageId=c1e30c18-db59-4bde-ab60-b9589922ab2e"},{"name":"7.流程文件的生成","url":"./w?sid=@sid&cmd=com.actionsoft.apps.cms_get_message&messageId=d799ced4-2313-45ba-911f-03cdb6db9e06"},{"name":"8.新建角色与岗位","url":"./w?sid=@sid&cmd=com.actiosoft.apps.cms_get_message&messageId=93559257-8280-444c-bd88-116748b919bf"}]}] {"control.risk":{"risk":{"desc":"描述企业内部流程涉及的各级风险点"},"control":{"desc":"描述企业内部流程涉及的各级风险的控制措施"}},"itsystem.normal":{"cloudServer":{"desc":"描述企业接入的云服务设施"},"database":{"desc":"描述企业提供的数据库服务类型,如某Oracle数据库"},"appSystem":{"desc":"描述企业提供的应用系统,如某供应链管理系统、业务流程管理平台"},"device":{"desc":"描述企业提供的各种IT设备"}},"control.kpi":{"kpi":{"desc":"从流程的目标(业务的目标、管理的要求等)出发设计流程绩效指标,用于衡量和评估末级流程的执行效果和对流程业务的支撑作用。"}},"process.evc":{"valueChain6":{"desc":"一个基本增值活动或辅助增值活动"},"valueChain5":{"desc":"一个基本增值活动或辅助增值活动"},"valueChain4":{"desc":"一个基本增值活动或辅助增值活动"},"valueChain3":{"desc":"一个基本增值活动或辅助增值活动"},"valueChain2":{"desc":"一个基本增值活动或辅助增值活动"},"valueChain1":{"desc":"一个基本增值活动或辅助增值活动"}},"control.policy":{"item":{"desc":"描述企业内部各级管理制度的具体条款"},"regulation":{"desc":"描述企业内部流程涉及的各级管理制度"}},"data.form":{"form":{"desc":"输入或输出的数据是一个完整的数据结构(或单据)"},"forms":{"desc":"输入或输出的数据由多个数据结构(或单据)组成"}},"process.flowchart":{"internalStorage":{"desc":"存储在存储器中的数据"},"predefinedProcess":{"desc":"在另外地方已得到详细说明的一个操作或一组操作"},"data":{"desc":"表示数据"},"document":{"desc":"表示属于该过程的书面信息"},"paperTape":{"desc":"旧式电脑使用的穿孔纸带输入"},"storedData":{"desc":"表示一般的数据存储"},"preparation":{"desc":"表示修改一条指令或一组指令以影响随后的活动"},"horizontalPool":{"desc":"包含多个泳道,对元素进行区分"},"verticalLane":{"desc":"对泳池里的流程元素的进行组织和分类"},"parallelMode":{"desc":"表示同步进行两个或两个以上并行方式的操作"},"terminator":{"desc":"表示过程的开始或结束"},"offPageReference":{"desc":"表示一组流程,可以用跨页引用进行标识"},"horizontalLane":{"desc":"对泳池里的流程元素的进行组织和分类"},"annotation":{"desc":"标识注解的内容"},"manualInput":{"desc":"人工输入的数据"},"onPageReference":{"desc":"表示流程图的待续,圈内有一子字母或数字"},"process":{"desc":"表示过程中的一个单独步骤"},"manualOperation":{"desc":"由人工完成的操作"},"loopLimit":{"desc":"去上角的上限值和去下角的下限值分别表示循环的开始和结束"},"decision":{"desc":"表示过程中的一项判定或一个分岔点"},"display":{"desc":"在机器上显示"},"verticalPool":{"desc":"包含多个泳道,对元素进行区分"},"sequentialData":{"desc":"老式磁带存储的数据"},"directData":{"desc":"表示流程图中存储在硬盘上的数据源"},"card":{"desc":"旧式电脑使用的打孔卡"}},"process.epc":{"or":{"desc":"表示一件事情可能产生的几个结果中,至少有一个会发生"},"method_service_node":{"desc":"描述流程中的手工活动"},"verticalPool":{"desc":"包含多个泳道,对元素进行区分"},"procedure":{"desc":"本流程的某个环节后引用的其它流程"},"method_approval_node":{"desc":"流程中审核、审批性质的活动"},"horizontalPool":{"desc":"包含多个泳道,对元素进行区分"},"verticalLane":{"desc":"对泳池里的流程元素的进行组织和分类"},"method_approval_node3":{"desc":"流程中需要执行某种操作的活动"},"and":{"desc":"表示一件事情可能产生的几个结果或后续活动,全部发生;或表示一件事情的发生需要几个条件同时满足"},"method_service_node4":{"desc":"描述流程中的手工活动"},"xor":{"desc":"表示一件事情可能产生的几个结果中,有且只有一个会发生"},"event":{"desc":"描述流程运行的状态"},"horizontalLane":{"desc":"对泳池里的流程元素的进行组织和分类"}},"org.role":{"role":{"desc":"一般用于表示执行某一流程步骤的流程角色"}},"process.bpmn2":{"signalIntermediateThrowingEvent":{"desc":"向外广播信号后,流程继续向后执行"},"callActivityCallingProcess":{"desc":"调用定义的全局过程"},"textAnnotation":{"desc":"给元素附加信息,便于理解"},"timerStartEvent":{"desc":"到达设置的日期/时间后,触发流程执行"},"horizontalPool":{"desc":"包含多个泳道,对元素进行区分"},"signalEndEvent":{"desc":"向外广播信号,结束所在分支的执行"},"verticalLane":{"desc":"对泳池里的流程元素的进行组织和分类"},"errorBoundaryInterrputingEvent":{"desc":"捕获活动内部抛出的错误信息,中断正常流程,触发错误处理流程"},"endEvent":{"desc":"结束所在分支的执行"},"serviceTask":{"desc":"使用Web服务或自动化应用的任务"},"exclusiveGateway":{"desc":""},"startEvent":{"desc":"触发流程的执行"},"receiveTask":{"desc":"等待并接受外部参与者发送的消息,消息接受完毕则任务执行完毕"},"signalStartEvent":{"desc":"接收信息,并触发流程的执行"},"messageIntermediateCatchEvent":{"desc":"捕获到特定消息后,该事件被触发,流程继续向后执行"},"messageIntermediateThrowingEvent":{"desc":"向其他参与方发送消息后,流程继续向后执行"},"signalIntermediateCatchEvent":{"desc":"捕获到其他参与方广播的信号后,该事件被触发,流程继续向后执行"},"errorEndEvent":{"desc":"错误结束事件"},"horizontalLane":{"desc":"对泳池里的流程元素的进行组织和分类"},"group":{"desc":"对元素进行分类,不影响流程的执行"},"scriptTask":{"desc":"定义一段执行脚本,由流程引擎执行,脚本执行完毕则任务执行完毕"},"businessRuleTask":{"desc":"调用业务规则引擎进行数据的计算并获得计算结果"},"manualTask":{"desc":"没有任何流程引擎和应用程序协助的纯手工任务"},"signalBoundaryInterrputingEvent":{"desc":"捕获特定信号,中断正常流程,触发异常处理流程"},"verticalPool":{"desc":"包含多个泳道,对元素进行区分"},"compensationBoundaryInterrputingEvent":{"desc":"捕获活动内部抛出的补偿信息,中断正常流程,触发执行补偿活动"},"userTask":{"desc":"在应用程序的协助下,由人工完成的任务"},"terminateEndEvent":{"desc":"结束所有分支的执行"},"messageStartEvent":{"desc":"接收消息,并触发流程的执行"},"messageEndEvent":{"desc":"向其他参与方发送消息,结束所在分支的执行"},"sendTask":{"desc":"向外部参与者发送消息,消息发送完毕则任务执行完毕"},"messageBoundaryInterrputingEvent":{"desc":"捕获特定消息,中断正常流程,触发异常处理流程"},"transaction":{"desc":"遵循特定事务规约的一系列活动"},"timerIntermediateCatchEvent":{"desc":"到达某个特定时间/日期后,触发该事件,流程继续向后执行"}},"org.normal":{"role":{"desc":"一般用于表示执行某一流程步骤的流程角色"},"organization":{"desc":"描述企业内部固定的组织单位"},"position":{"desc":"描述企业内部各部门的实际岗位"},"employee":{"desc":"表示企业的具体员工"}}} false + 09e17771-5bc6-41c3-8b29-4bb345810967 diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEDesignerVersionController.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEDesignerVersionController.java new file mode 100644 index 00000000..51dc778d --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEDesignerVersionController.java @@ -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); + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEPALController.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEPALController.java index 2431d66a..e4aa0381 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEPALController.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEPALController.java @@ -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); } /** diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/components/model/PALSecurityLevelModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/components/model/PALSecurityLevelModel.java new file mode 100644 index 00000000..669950d0 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/components/model/PALSecurityLevelModel.java @@ -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; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/PALBasicMethodCache.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/PALBasicMethodCache.java new file mode 100644 index 00000000..8d4762f2 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/PALBasicMethodCache.java @@ -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 { + + 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 getAllBasicMethodModel() { + Iterator iterator = getCache().iterator(); + return iteratorToList(iterator); + } + + /** + * 根据资产库获取该资产库下全部建模方法基础信息List + * + * @return + */ + public static List getAllBasicMethodModel(String wsId) { + Iterator iterators = getCache().getByIndex(PALBasicMethodCacheIndex2.class, wsId); + return iteratorToList(iterators); + } + + /** + * 根据appId获取该appId下全部建模方法 + * + * @param appId 应用id + * @return methodIds + */ + public static List getMethodIdByAppId(String appId) { + List 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 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() { + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/PALMethodSchemaCache.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/PALMethodSchemaCache.java new file mode 100644 index 00000000..4473a09b --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/PALMethodSchemaCache.java @@ -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 { + + 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 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 shapeAllowOccurrence(String wsId, String methodId) { + PALMethodSchemaModel schemaModel = getModelListByMethodIdAndLangAndWsId(methodId, I18nRes.getUserLanguage(), wsId); + if (schemaModel != null) { + List 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 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 list = getModelListByMethodId(methodId); + if (list != null) { + for (PALMethodSchemaModel model : list) { + removeModelById(model.getId()); + } + } + } + + public static void removeByMethodIdAndWsId(String methodId, String wsId) { + List list = getModelListByMethodId(methodId); + if (list != null) { + for (PALMethodSchemaModel model : list) { + if (model.getWsId().equals(wsId)) + removeModelById(model.getId()); + } + } + } + + public static void removeAll() { + Iterator 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() { + } + +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALBasicMethodCacheIndex1.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALBasicMethodCacheIndex1.java new file mode 100644 index 00000000..a2dddf05 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALBasicMethodCacheIndex1.java @@ -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 { + @Override + public String key(PALBasicMethodModel t) { + return t.getMethodId() + "-" + t.getWsId(); + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALBasicMethodCacheIndex2.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALBasicMethodCacheIndex2.java new file mode 100644 index 00000000..5550d868 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALBasicMethodCacheIndex2.java @@ -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 { + @Override + public String key(PALBasicMethodModel t) { + return t.getWsId(); + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALBasicMethodCacheIndex3.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALBasicMethodCacheIndex3.java new file mode 100644 index 00000000..dc230286 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALBasicMethodCacheIndex3.java @@ -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 { + @Override + public String key(PALBasicMethodModel t) { + return t.getMethodId(); + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex1.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex1.java new file mode 100644 index 00000000..f2c60c9c --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex1.java @@ -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 { + @Override + public String key(PALMethodSchemaModel palMethodSchemaModel) { + return palMethodSchemaModel.getMethodId(); + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex2.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex2.java new file mode 100644 index 00000000..5ddd6694 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex2.java @@ -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 { + @Override + public String key(PALMethodSchemaModel palMethodSchemaModel) { + return palMethodSchemaModel.getMethodId() + "-" + palMethodSchemaModel.getLang(); + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex3.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex3.java new file mode 100644 index 00000000..14412a77 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex3.java @@ -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 { + @Override + public String key(PALMethodSchemaModel model) { + return model.getMethodId() + "-" + model.getWsId() + "-" + model.getLang(); + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex4.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex4.java new file mode 100644 index 00000000..52b829ab --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/cache/index/PALMethodSchemaCacheIndex4.java @@ -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 { + @Override + public String key(PALMethodSchemaModel palMethodSchemaModel) { + return palMethodSchemaModel.getWsId(); + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/constant/MethodSchemaConst.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/constant/MethodSchemaConst.java new file mode 100644 index 00000000..e33ccdec --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/constant/MethodSchemaConst.java @@ -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"; +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/constant/PALMethodConst.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/constant/PALMethodConst.java index a7bf7cd2..fac9fe15 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/constant/PALMethodConst.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/constant/PALMethodConst.java @@ -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"; } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALBasicMethodModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALBasicMethodModel.java new file mode 100644 index 00000000..019299d5 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALBasicMethodModel.java @@ -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 + '}'; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodAttributeModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodAttributeModel.java index 137fe1db..87f126e1 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodAttributeModel.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodAttributeModel.java @@ -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; + } } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodCategorySchemaModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodCategorySchemaModel.java new file mode 100644 index 00000000..dc64a1e8 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodCategorySchemaModel.java @@ -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; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodFunctionSchemaModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodFunctionSchemaModel.java new file mode 100644 index 00000000..0224b88d --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodFunctionSchemaModel.java @@ -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; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodGlobalCommandSchemaModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodGlobalCommandSchemaModel.java new file mode 100644 index 00000000..3172493f --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodGlobalCommandSchemaModel.java @@ -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; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodSchemaModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodSchemaModel.java new file mode 100755 index 00000000..a6acccc5 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodSchemaModel.java @@ -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 categorySchemaList;// 图元分组List + private List globalCommandSchemaList;// canvas片段引用List + private List shapeSchemaList;// 形状定义List + private List 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 getCategorySchemaList() { + if (CollectionUtils.isEmpty(categorySchemaList)) { + return new ArrayList<>(); + } + return categorySchemaList; + } + + public void setCategorySchemaList(List categorySchemaList) { + this.categorySchemaList = categorySchemaList; + } + + public List getGlobalCommandSchemaList() { + if (CollectionUtils.isEmpty(globalCommandSchemaList)) { + return new ArrayList<>(); + } + return globalCommandSchemaList; + } + + public void setGlobalCommandSchemaList(List globalCommandSchemaList) { + this.globalCommandSchemaList = globalCommandSchemaList; + } + + public List getShapeSchemaList() { + if (CollectionUtils.isEmpty(shapeSchemaList)) { + return new ArrayList<>(); + } + return shapeSchemaList; + } + + public void setShapeSchemaList(List shapeSchemaList) { + this.shapeSchemaList = shapeSchemaList; + } + + public List getFunctionSchemaList() { + if (CollectionUtils.isEmpty(functionSchemaList)) { + return new ArrayList<>(); + } + return functionSchemaList; + } + + public void setFunctionSchemaList(List functionSchemaList) { + this.functionSchemaList = functionSchemaList; + } + + @Override + public String toString() { + return "PALMethodSchemaModel{" + "id='" + id + '\'' + ", methodId='" + methodId + '\'' + ", appId='" + appId + '\'' + ", lang='" + lang + '\'' + ", lastModified=" + lastModified + ", schema='" + schema + '\'' + ", customSchema='" + customSchema + '\'' + '}'; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodShapeSchemaModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodShapeSchemaModel.java new file mode 100644 index 00000000..8ad8d27f --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/model/PALMethodShapeSchemaModel.java @@ -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; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/util/PALMethodSchemaUtil.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/util/PALMethodSchemaUtil.java new file mode 100644 index 00000000..c95868c1 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/util/PALMethodSchemaUtil.java @@ -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 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 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 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 shapeSortList = new ArrayList<>(Arrays.asList(shapeSort.split(","))); + Map schemaMap = new HashMap<>(); + List 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 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 shapes) { +// String lang = I18nRes.getUserLanguage(); +// PALMethodSchemaModel schemaModel = PALMethodSchemaCache.getModelListByMethodIdAndLangAndWsId(methodId, lang, wsId); +// if (schemaModel == null) { +// return; +// } +// List 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 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 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 目标语言代码,指定要将词汇翻译成的语言,例如cn、en、big5 +// * @return 转换后的模式字符串,其中的关键词被翻译成指定语言 +// */ +// public static String transformSchemaByLanguage(AppContext app, String originalSchema, String lang) { +// return transformSchemaByLanguage(app.getId(), originalSchema, lang); +// } +// +// /** +// * 根据指定语言翻译形状定义信息 +// * +// * @param appId 应用ID +// * @param originalSchema 原始形状定义信息 +// * @param lang 目标语言代码,指定要将词汇翻译成的语言,例如cn、en、big5 +// * @return 转换后的模式字符串,其中的关键词被翻译成指定语言 +// */ +// public static String transformSchemaByLanguage(String appId, String originalSchema, String lang) { +// Map> map = I18nRes.getResourceMapByApp(appId); +// // 对map的键进行排序,确保更长的键先被处理,并且只包含中文字符的键被加入 +// Map> sortedMap = new TreeMap<>(Comparator.comparingInt(String::length).reversed() // 首先根据字符串长度排序 +// .thenComparing(Comparator.naturalOrder())); // 长度相同则根据字符串的自然顺序排序 +// +// // 正则表达式,用于检测字符串中是否包含中文字符(不含中文字符,会造成后续判断误伤) +// String chineseCharactersPattern = "[\u4e00-\u9fa5]"; +// +// // 过滤并放入sortedMap +// for (Map.Entry> 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 目标语言代码,指定要将词汇翻译成的语言,例如cn、en、big5 +// * @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 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 schemaKeys) { +// try { +// Element rootElement = schemaDocument.getRootElement(); +// +// // 构建图元分类 +// List categoryList = buildSchemaList(methodId, rootElement, MethodSchemaEnum.SCHEMA_CATEGORY, PALMethodCategorySchemaModel.class, appId, lang); +// psmm.setCategorySchemaList(categoryList); +// +// // 构建function +// List functionList = buildSchemaList(methodId, rootElement, MethodSchemaEnum.SCHEMA_FUNCTION, PALMethodFunctionSchemaModel.class, appId, lang); +// psmm.setFunctionSchemaList(functionList); +// +// // 构建canvas片段引用 +// List globalCommandList = buildSchemaList(methodId, rootElement, MethodSchemaEnum.SCHEMA_GLOBAL_COMMAND, PALMethodGlobalCommandSchemaModel.class, appId, lang); +// psmm.setGlobalCommandSchemaList(globalCommandList); +// +// // 构建形状定义 +// List 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 schemaKeys) { +// // 缓存更新 +// PALMethodSchemaCache.removeByMethodIdAndWsId(methodId, wsId); +// List 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 List buildSchemaList(String methodId, Element rootElement, MethodSchemaEnum schemaEnum, Class 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 List buildSchemaList(String methodId, Element rootElement, MethodSchemaEnum schemaEnum, Class modelClass, String appId, String lang, Set schemaKeys) { +// List modelList = new ArrayList<>(); +// Element schemaElement = rootElement.element(schemaEnum.getTagGroupName()); +// if (schemaElement != null) { +// List 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 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 methodList = new ArrayList<>(); +// List 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 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 methodIds) { +// JSONObject functionObj = new JSONObject(); +// // 获取所有的functions +// for (String methodId : methodIds) { +// PALMethodSchemaModel schemaModel = PALMethodSchemaCache.getModelListByMethodIdAndLangAndWsId(methodId, I18nRes.getUserLanguage(), wsId); +// if (schemaModel == null) { +// continue; +// } +// // 拼接function +// List 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 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(); +// } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/util/PALMethodUtil.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/util/PALMethodUtil.java index 22174538..f3ed9ca0 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/util/PALMethodUtil.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/method/util/PALMethodUtil.java @@ -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 = ""; + color = "#FFB718"; + } else { + PALBasicMethodModel model = PALBasicMethodCache.getModelByMethodIdAndWsId(methodId, wsId); + if (model == null) { + code = ""; + color = "#FFB718"; + } else { + code = model.getIconCode(); + color = model.getIconColor(); + } + } + JSONObject result = new JSONObject(); + result.put("code", code); + result.put("color", color); + return result; + } } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/processexec/ProcessExecAPIManager.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/processexec/ProcessExecAPIManager.java new file mode 100644 index 00000000..1d06851b --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/processexec/ProcessExecAPIManager.java @@ -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; + } + +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/processexec/constant/B2PControlModeEnum.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/processexec/constant/B2PControlModeEnum.java new file mode 100644 index 00000000..0847eb2e --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/processexec/constant/B2PControlModeEnum.java @@ -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; + } +} + + diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/processexec/constant/P2BControlModeEnum.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/processexec/constant/P2BControlModeEnum.java new file mode 100644 index 00000000..b090bdcd --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/processexec/constant/P2BControlModeEnum.java @@ -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; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/CoeDesignerShapeAPIManager.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/CoeDesignerShapeAPIManager.java index 6fc49534..c3bdd709 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/CoeDesignerShapeAPIManager.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/CoeDesignerShapeAPIManager.java @@ -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 getAllValidAndUseShapeAttributeModelsMap(String wsId, String methodId) { + return getAllValidAndUseShapeAttributeModels(wsId, methodId).stream().collect(Collectors.toMap(PALMethodAttributeModel::getKey, Function.identity())); + } } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/constant/CoeDesignerConstant.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/constant/CoeDesignerConstant.java index 8ebc1879..0cbabcd4 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/constant/CoeDesignerConstant.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/constant/CoeDesignerConstant.java @@ -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"; } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/constant/DiffNodeTypeEnum.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/constant/DiffNodeTypeEnum.java new file mode 100644 index 00000000..170d8206 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/constant/DiffNodeTypeEnum.java @@ -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; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/constant/VersionStatusEnum.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/constant/VersionStatusEnum.java new file mode 100644 index 00000000..2035c0f7 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/constant/VersionStatusEnum.java @@ -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 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 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; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/dto/VersionCompareDTO.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/dto/VersionCompareDTO.java new file mode 100644 index 00000000..59871aa2 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/dto/VersionCompareDTO.java @@ -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; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/dto/VersionListDTO.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/dto/VersionListDTO.java new file mode 100644 index 00000000..ff485638 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/dto/VersionListDTO.java @@ -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; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/image/util/CoeDesignerImageUtil.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/image/util/CoeDesignerImageUtil.java new file mode 100644 index 00000000..ec056f6a --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/image/util/CoeDesignerImageUtil.java @@ -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); +// } +// +// /** +// * 获取 形状图片数据 名称,内容数据
+// * 即key:imageId, 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); +// } +// +// /** +// * 获取 形状图片数据 名称,内容数据
+// * 即key:imageId, 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 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(" +// * 即 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 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); +// } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/util/DesignerVersionUtil.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/util/DesignerVersionUtil.java new file mode 100644 index 00000000..71225638 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/util/DesignerVersionUtil.java @@ -0,0 +1,1417 @@ +package com.actionsoft.apps.coe.pal.pal.repository.designer.util; + +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.IteratorUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.actionsoft.apps.coe.pal.components.model.PALSecurityLevelModel; +import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodAttributeModel; +import com.actionsoft.apps.coe.pal.pal.method.util.PALMethodUtil; +import com.actionsoft.apps.coe.pal.pal.processexec.ProcessExecAPIManager; +import com.actionsoft.apps.coe.pal.pal.repository.PALRepositoryAPIManager; +import com.actionsoft.apps.coe.pal.pal.repository.PALRepositoryQueryAPIManager; +import com.actionsoft.apps.coe.pal.pal.repository.cache.PALRepositoryCache; +import com.actionsoft.apps.coe.pal.pal.repository.cache.PALRepositoryPropertyCache; +import com.actionsoft.apps.coe.pal.pal.repository.designer.CoeDesignerShapeAPIManager; +import com.actionsoft.apps.coe.pal.pal.repository.designer.constant.DiffNodeTypeEnum; +import com.actionsoft.apps.coe.pal.pal.repository.designer.constant.VersionStatusEnum; +import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.cache.DesignerShapeRelationCache; +import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.dao.DesignerShapeRelationDao; +import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.model.DesignerShapeRelationModel; +import com.actionsoft.apps.coe.pal.pal.repository.designer.vo.AttrVO; +import com.actionsoft.apps.coe.pal.pal.repository.designer.vo.DiffNodeVO; +import com.actionsoft.apps.coe.pal.pal.repository.designer.vo.ShapeLinkVO; +import com.actionsoft.apps.coe.pal.pal.repository.designer.vo.UpFileVO; +import com.actionsoft.apps.coe.pal.pal.repository.designer.vo.VersionListVO; +import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryModel; +import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryPropertyModel; +import com.actionsoft.apps.coe.pal.pal.repository.upfile.cache.PALUpfileCache; +import com.actionsoft.apps.coe.pal.pal.repository.upfile.model.UpfileModel; +import com.actionsoft.apps.coe.pal.pal.repository.upfile.util.CoeUpFileUtil; +import com.actionsoft.apps.coe.pal.pal.ws.web.VersionUtil; +import com.actionsoft.apps.coe.pal.util.HighSecurityUtil; +import com.actionsoft.bpms.bpmn.engine.model.def.ProcessDefinition; +import com.actionsoft.bpms.org.model.DepartmentModel; +import com.actionsoft.bpms.org.model.RoleModel; +import com.actionsoft.bpms.org.model.UserModel; +import com.actionsoft.bpms.server.UserContext; +import com.actionsoft.bpms.server.fs.DCContext; +import com.actionsoft.bpms.util.UtilDate; +import com.actionsoft.bpms.util.UtilString; +import com.actionsoft.sdk.local.SDK; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +/** + * @author oYang + * @Description 设计器版本工具类 + * @createTime 2024年07月29日 14:49:00 + */ +public class DesignerVersionUtil { + + private static final Logger log = LoggerFactory.getLogger(DesignerVersionUtil.class); + + /** + * 返回版本状态 + * + * @param model 当前模型 + * @return 版本状态 + */ + public static VersionStatusEnum getVersionStatus(PALRepositoryModel model) { + if (model.isApproval()) { + return VersionStatusEnum.APPROVAL; + } + if (model.isStop()) { + return VersionStatusEnum.STOP; + } + if (model.isPublish()) { + return VersionStatusEnum.PUBLISH; + } + if (model.isUse()) { + return VersionStatusEnum.USE; + } + return VersionStatusEnum.DESIGNER; + } + + /** + * 获取版本列表Vo + * + * @param id PAL模型Id + * @param mapOfProcessDefId PAL模型ID与bpm流程定义Id映射 + * @return List + */ + public static List getVersionListVoList(String id, Map mapOfProcessDefId) { + List result = new ArrayList<>(); + PALRepositoryModel model = PALRepositoryCache.getCache().get(id); + List versions = PALRepositoryCache.getByVersionId(model.getVersionId()); + versions.sort((o1, o2) -> VersionUtil.compareVersionNo(o1.getVersion(), o2.getVersion(), true)); + for (PALRepositoryModel palModel : versions) { + //隐藏与bpm关联流程 + if (mapOfProcessDefId.containsKey(palModel.getId())) { + continue; + } + VersionListVO versionListVo = getVersionListVo(palModel); + result.add(versionListVo); + } + return result; + } + + /** + * 获取版本列表Vo + * + * @param palModel pal模型 + * @return VersionListVo + */ + public static VersionListVO getVersionListVo(PALRepositoryModel palModel) { + String plId = palModel.getId(); + String verAndVerD = String.valueOf(palModel.getVersion()); + try{ + verAndVerD = VersionUtil.getVersionStr(Double.parseDouble(verAndVerD)); + }catch (Exception e){ + log.error("版本号转换异常:{}", verAndVerD); + } + VersionStatusEnum versionStatus = getVersionStatus(palModel); + // 创建人 + String createUser = getUserName(palModel.getCreateUser()); + // 创建时间 + String createTime = getDate(palModel.getCreateDate()); + // 更新人 + String updateUser = getUserName(palModel.getModifyUser()); + // 更新时间 + String updateTime = getModifyDate(palModel.getModifyDate()); + // 梳理到执行 流程是否重命名、新建版本 受到参数管控 + boolean hasProcessControlPerm = !PALRepositoryQueryAPIManager.getInstance().isCorrelateBpms(plId, true) || ProcessExecAPIManager.getInstance().hasProcessControlPerm(plId); + return VersionListVO.VersionListBuilder.createBuilder().withPlId(plId).withVersionId(palModel.getVersionId()).withVersionNo(verAndVerD).withVersionStatus(versionStatus.getCode()).withCreateUser(createUser).withCreateTime(createTime).withUpdateUser(updateUser).withUpdateTime(updateTime).withHasCreatePerm(hasProcessControlPerm).build(); + } + + /** + * 获取版本列表Vo + * + * @param palModel pal模型 + * @param processDefinition bpm平台流程定义信息 + * @param correlateTime 关联时间 + * @return VersionListVo + */ + public static VersionListVO getVersionListVo(PALRepositoryModel palModel, ProcessDefinition processDefinition, Timestamp correlateTime) { + String plId = palModel.getId(); + String versionId = palModel.getVersionId(); + // PAL端版本号 + String palVersionNo = String.valueOf(palModel.getVersion()); + // 版本状态 + VersionStatusEnum versionStatus = getVersionStatus(palModel); + // 创建人 + String createUser = getUserName(processDefinition.getCreateUser()); + // 创建时间 + String createTime = getDate(processDefinition.getCreateTime()); + // 更新人 + String updateUser = getUserName(processDefinition.getUpdateUser()); + // 更新时间 + String updateTime = getModifyDate(processDefinition.getUpdateTime()); + // 梳理到执行 流程是否重命名、新建版本 受到参数管控 + boolean hasProcessControlPerm = !PALRepositoryQueryAPIManager.getInstance().isCorrelateBpms(plId, true) || ProcessExecAPIManager.getInstance().hasProcessControlPerm(plId); + return VersionListVO.VersionListBuilder.createBuilder().withPlId(plId).withVersionId(versionId).withVersionNo(palVersionNo).withVersionStatus(versionStatus.getCode()).withCreateUser(createUser).withCreateTime(createTime).withUpdateUser(updateUser).withUpdateTime(updateTime).withHasCreatePerm(hasProcessControlPerm).withCorrelateTime(correlateTime).build(); + } + + private static String getUserName(String userId) { + return SDK.getORGAPI().getUser(userId) == null ? userId : SDK.getORGAPI().getUser(userId).getUserNameI18N(); + } + + private static String getDate(Timestamp date) { + return UtilDate.dateFormat(date); + } + + private static String getModifyDate(Timestamp date) { + if (date == null) { + return null; + } + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + return sdf.format(date); + } + + /** + * 获取版本对比数据 + * + * @param plId pal模型Id + */ + public static JSONObject getVersionData(UserContext uc, String plId, String teamId) { + PALRepositoryModel plModel = PALRepositoryCache.getCache().get(plId); + if (plModel == null) { + return null; + } + String definition = PALRepositoryQueryAPIManager.getInstance().getProcessDefinition(uc, plId); + return getVersionData(uc, plModel, teamId, definition); + } + + + /** + * 获取版本对比数据 + * + * @param plModel pal模型 + */ + public static JSONObject getVersionData(UserContext uc, PALRepositoryModel plModel, String teamId, String definition) { + if (plModel == null) { + return null; + } + String plId = plModel.getId(); + JSONObject result = new JSONObject(); + // 版本号 + String versionNo = String.valueOf(plModel.getVersion()); + try{ + versionNo = VersionUtil.getVersionStr(plModel.getVersion()); + }catch (Exception e){ + log.error("版本号转换异常:{}", versionNo); + } + result.put("versionNo", versionNo); + result.put("plId", plId); + result.put("updateTime", getModifyDate(plModel.getModifyDate())); + // 模型定义信息 + result.put("definition", definition); + // 形状属性 + Map attrKeyAndModelMap = CoeDesignerShapeAPIManager.getInstance().getAllValidAndUseShapeAttributeModelsMap(plModel.getWsId(), plModel.getMethodId()); + Map> shapeAttr = getShapeAttrForCompare(uc, plId, definition, attrKeyAndModelMap); + result.put("shapeAttr", shapeAttr); + // 形状附件 + Map shapeFile = getShapeFileList(uc, plId, definition); + result.put("shapeUpFile", shapeFile); + // 形状关联附件 + Map relationShapeFileList = getRelationShapeFileList(uc, plId, definition); + result.put("shapeRelationUpFile", relationShapeFileList); + // 形状链接 + Map shapeLink = getShapeLinkList(uc, definition, teamId); + result.put("shapeLink", shapeLink); + // 文件属性 + List fileAttrForCompare = getFileAttrForCompare(uc, plId); + result.put("fileAttr", fileAttrForCompare); + // 文件附件 + JSONObject fileUpFileList = getFileUpFileList(uc, plId); + result.put("fileUpFile", fileUpFileList); + // 文件关联附件 + JSONObject fileRelationUpFileList = getFileRelationUpFileList(uc, plId); + result.put("fileRelationUpFile", fileRelationUpFileList); + return result; + } + + /** + * 获取形状Id集合 + * + * @param definition 模型定义信息 + * @return List + */ + public static List getShapeIdsByDefinition(String definition) { + JSONObject definitionObj = validateDefinition(definition); + if (definitionObj == null) { + return null; + } + JSONObject elements = definitionObj.getJSONObject("elements"); + return elements.values().stream().map(o -> (JSONObject) o).filter(o -> !"linker".equals(o.getString("name"))).map(o -> o.getString("id")).collect(Collectors.toList()); + } + + /** + * 获取形状属性 + * + * @param definition 模型定义信息 + */ + public static Map> getShapeAttrForCompare(UserContext uc, String plId, String definition, Map attrKeyAndModelMap) { + JSONObject definitionObj = validateDefinition(definition); + + if (definitionObj != null) { + JSONObject elements = definitionObj.getJSONObject("elements"); + List listOfShapeId = getShapeIdsByDefinition(definition); + if (CollectionUtils.isNotEmpty(listOfShapeId)) { + Map> mapOfShapeAttr = new HashMap<>(); + listOfShapeId.forEach(shapeId -> { + List listOfShapeAttr = new ArrayList<>(); + JSONObject shape = elements.getJSONObject(shapeId); + if (shape.containsKey("dataAttributes")) { + JSONArray dataAttributes = shape.getJSONArray("dataAttributes"); + if (CollectionUtils.isNotEmpty(dataAttributes)) { + dataAttributes.stream().map(o -> (JSONObject) o).forEach(o -> { + if (o.containsKey("attributesJsonArray")) { + JSONArray attributesJsonArray = o.getJSONArray("attributesJsonArray"); + attributesJsonArray.stream().map(item -> (JSONObject) item).forEach(item -> { + String key = item.getString("key"); + if (attrKeyAndModelMap.containsKey(key)) { + PALMethodAttributeModel attrModel = attrKeyAndModelMap.get(key); + String name = attrModel.getNewTitle(); + String type = attrModel.getType(); + Object value = item.getString("value"); + String ref = attrModel.getRef(); + + Map shapeAttrValue = getShapeAttrValue(uc, plId, shapeId, type, key, value, ref); + value = shapeAttrValue.get("value"); + Object compareAccord = shapeAttrValue.get("compareAccord"); + AttrVO shapeAttrVO = AttrVO.Builder.createBuilder().withId(key).withName(name).withType(type).withValue(value).withCompareAccord(compareAccord).withIsDiff(false).build(); + listOfShapeAttr.add(shapeAttrVO); + } + }); + } + }); + } + } + sortAttrVO(listOfShapeAttr, attrKeyAndModelMap); + mapOfShapeAttr.put(shapeId, listOfShapeAttr); + }); + return mapOfShapeAttr; + } + } + return null; + } + + private static Map getShapeAttrValue(UserContext uc, String plId, String shapeId, String type, String attrId, Object value, String ref) { + Map result = null; + switch (type) { + case "relation": + result = getShapeAttrOfRelation(plId, shapeId, attrId, ref); + break; + case "awsorg": + result = getShapeAttrOfAwsOrg(plId, shapeId, attrId); + break; + case "file": + result = getShapeAttrUpFileList(uc, plId, shapeId, attrId); + break; + default: + result = new HashMap<>(); + result.put("value", value); + result.put("compareAccord", sortStringContent(value.toString())); + break; + } + return result; + } + + /** + * 获取形状属性(附件信息) + * + * @param uc 用户上下文 + * @param plId pal模型Id + * @param shapeId 形状Id + * @param attrId 属性Id + * @return Map + */ + public static Map getShapeAttrUpFileList(UserContext uc, String plId, String shapeId, String attrId) { + JSONArray listOfFileAttrValue = new JSONArray(); + JSONArray listOfCompareAccord = new JSONArray(); + List upfileModelList = PALUpfileCache.getByPlUuid(plId); + upfileModelList = upfileModelList.stream().filter(upfileModel -> upfileModel.getType().equals("a")).filter(upfileModel -> shapeId.equals(upfileModel.getShape_uuid())).filter(upfileModel -> attrId.equals(upfileModel.getAttrId())).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(upfileModelList)) { + upfileModelList.forEach(upfileModel -> { + JSONObject valueObj = new JSONObject(); + String fileName = upfileModel.getFileName(); + String downloadUrl = getDownloadUrl(uc, upfileModel); + valueObj.put("fileName", fileName); + valueObj.put("downloadUrl", downloadUrl); + listOfFileAttrValue.add(valueObj); + String compareAccord = upfileModel.getShape_uuid() + "_" + upfileModel.getAttrId() + "_" + upfileModel.getFileName(); + listOfCompareAccord.add(compareAccord); + }); + } + Map mapOfFileAttrValue = new HashMap<>(); + mapOfFileAttrValue.put("value", listOfFileAttrValue); + mapOfFileAttrValue.put("compareAccord", listOfCompareAccord); + return mapOfFileAttrValue; + } + + /** + * 获取形状属性(模型关联) + * + * @param plId pal模型Id + * @param shapeId 形状Id + * @param attrId 属性Id + * @param ref 关联属性配置信息 + * @return Map + */ + private static Map getShapeAttrOfRelation(String plId, String shapeId, String attrId, String ref) { + JSONArray fileAttrValueArray = new JSONArray(); + JSONArray compareAccordArray = new JSONArray(); + List relationModelList = DesignerShapeRelationCache.getListByAttrId(plId, shapeId, attrId); + if (CollectionUtils.isNotEmpty(relationModelList)) { + relationModelList.forEach(relationModel -> { + JSONObject refObj = JSONObject.parseObject(ref); + String relationTyp = refObj.containsKey("type") ? refObj.getString("type") : "shape"; + String relationFileId = relationModel.getRelationFileId(); + if ("file".equals(relationTyp)) { + PALRepositoryModel model = PALRepositoryCache.getCache().get(relationFileId); + if (model != null) { + fileAttrValueArray.add(model.getName()); + compareAccordArray.add(relationFileId); + } + } else { + fileAttrValueArray.add(relationModel.getRelationShapeText()); + compareAccordArray.add(relationFileId + "_" + relationModel.getRelationShapeId()); + } + }); + } + Map fileAttrValueMap = new HashMap<>(); + fileAttrValueMap.put("value", fileAttrValueArray); + fileAttrValueMap.put("compareAccord", compareAccordArray); + return fileAttrValueMap; + } + + /** + * 获取形状属性(关联AWS组织) + * + * @param plId pal模型Id + * @param shapeId 形状Id + * @param attrId 属性Id + * @return Map + */ + private static Map getShapeAttrOfAwsOrg(String plId, String shapeId, String attrId) { + JSONArray listOfFileAttrValue = new JSONArray(); + JSONArray listOfCompareAccord = new JSONArray(); + List listOfRelationModel = DesignerShapeRelationCache.getListByAttrId(plId, shapeId, attrId); + if (CollectionUtils.isNotEmpty(listOfRelationModel)) { + listOfRelationModel.forEach(relationModel -> { + if ("00000000-0000-0000-0000-000000000000".equals(relationModel.getRelationFileId()) && "00000000-0000-0000-0000-000000000000".equals(relationModel.getRelationShapeId())) { + JSONObject object = JSONObject.parseObject(relationModel.getRelationShapeText()); + listOfCompareAccord.add(shapeId + "_" + object.getString("type") + "_" + object.getString("id")); + if ("department".equals(object.getString("type"))) { + DepartmentModel dept = SDK.getORGAPI().getDepartmentById(object.getString("id")); + if (dept != null) { + listOfFileAttrValue.add(dept.getName()); + } + } + if ("position".equals(object.getString("type"))) {// 岗位,先用角色代替 + RoleModel role = SDK.getORGAPI().getRoleById(object.getString("id")); + if (role != null) { + listOfFileAttrValue.add(role.getName()); + } + } + if ("user".equals(object.getString("type"))) { + UserModel user = SDK.getORGAPI().getUser(object.getString("id")); + if (user != null) { + listOfFileAttrValue.add(user.getUserName()); + } + } + if ("role".equals(object.getString("type"))) { + RoleModel role = SDK.getORGAPI().getRoleById(object.getString("id")); + if (role != null) { + listOfFileAttrValue.add(role.getName()); + } + } + } + }); + } + Map mapOfFileAttrValue = new HashMap<>(); + mapOfFileAttrValue.put("value", listOfFileAttrValue); + mapOfFileAttrValue.put("compareAccord", listOfCompareAccord); + return mapOfFileAttrValue; + } + + /** + * 获取形状文件信息 + * + * @param plId pal模型Id + * @param definition 模型定义信息 + * @return Map> + */ + public static Map getShapeFileList(UserContext uc, String plId, String definition) { + List listOfShapeId = getShapeIdsByDefinition(definition); + if (CollectionUtils.isNotEmpty(listOfShapeId)) { + Map mapOfShapeFile = new HashMap<>(); + listOfShapeId.forEach(shapeId -> { + JSONObject shapeFileObj = new JSONObject(); + shapeFileObj.put("isDiff", false); + List listOfShapeFile = new ArrayList<>(); + List listOfUpFile = PALUpfileCache.getByPlUuid(plId); + if (CollectionUtils.isNotEmpty(listOfUpFile)) { + listOfUpFile.stream().filter(item -> item.getType().equals("s")).filter(item -> item.getShape_uuid().equals(shapeId)).forEach(item -> { + UpFileVO upFileVO = getUpFileVO(uc, item); + listOfShapeFile.add((JSONObject) JSONObject.toJSON(upFileVO)); + }); + } + shapeFileObj.put("value", listOfShapeFile); + mapOfShapeFile.put(shapeId, shapeFileObj); + }); + return mapOfShapeFile; + } + return null; + } + + /** + * 获取关联的形状文件信息 + * + * @param uc 用户上下文 + * @param plId pal模型Id + * @param definition 模型定义信息 + * @return Map> + */ + public static Map getRelationShapeFileList(UserContext uc, String plId, String definition) { + List listOfShapeId = getShapeIdsByDefinition(definition); + if (CollectionUtils.isNotEmpty(listOfShapeId)) { + Map mapOfRelationShapeFile = new HashMap<>(); + listOfShapeId.forEach(shapeId -> { + JSONObject shapeFileObj = new JSONObject(); + shapeFileObj.put("isDiff", false); + List listOfShapeFile = new ArrayList<>(); + List listOfShapeRelation = IteratorUtils.toList(DesignerShapeRelationCache.getByShapeId(plId, shapeId)); + if (CollectionUtils.isNotEmpty(listOfShapeRelation)) { + listOfShapeRelation.forEach(item -> { + String relationFileId = item.getRelationFileId(); + String relationShapeId = item.getRelationShapeId(); + List listOfUpFile = PALUpfileCache.getByPlUuid(relationFileId); + if (UtilString.isEmpty(relationShapeId)) { // 关联的文件 获取关联文件的附件 + listOfUpFile = listOfUpFile.stream().filter(u -> u.getType().equals("f")).collect(Collectors.toList()); + } else { // 关联的形状 获取关联的形状附件 + listOfUpFile = listOfUpFile.stream().filter(u -> u.getType().equals("s")).filter(u -> u.getShape_uuid().equals(item.getRelationShapeId())).collect(Collectors.toList()); + } + if (CollectionUtils.isNotEmpty(listOfUpFile)) { + listOfUpFile.forEach(u -> { + UpFileVO upFileVO = getUpFileVO(uc, u); + listOfShapeFile.add((JSONObject) JSONObject.toJSON(upFileVO)); + }); + } + }); + } + shapeFileObj.put("value", listOfShapeFile); + mapOfRelationShapeFile.put(shapeId, shapeFileObj); + }); + return mapOfRelationShapeFile; + } + return null; + } + + private static UpFileVO getUpFileVO(UserContext uc, UpfileModel model) { + String downloadUrl = getDownloadUrl(uc, model); + boolean 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) { + hasSecurity = false; + } + } + return UpFileVO.Builder.createBuilder().withFileId(model.getUuid()).withFileName(model.getFileName()).withDownloadUrl(downloadUrl).withHasSecurity(hasSecurity).build(); + } + + /** + * 获取下载地址 + * + * @param uc UserContext + * @param model UpfileModel + * @return String + */ + private static String getDownloadUrl(UserContext uc, UpfileModel model) { + DCContext dcContext = CoeUpFileUtil.getUpFileDCContext(uc, model); + return dcContext != null ? dcContext.getDownloadURL() : ""; + } + + /** + * 获取形状链接信息 + * + * @param definition 模型定义信息 + * @return Map> + */ + public static Map getShapeLinkList(UserContext uc, String definition, String teamId) { + JSONObject definitionObj = validateDefinition(definition); + + if (definitionObj != null) { + JSONObject elements = definitionObj.getJSONObject("elements"); + List listOfShapeId = getShapeIdsByDefinition(definition); + if (CollectionUtils.isNotEmpty(listOfShapeId)) { + Map mapOfShapeLink = new HashMap<>(); + listOfShapeId.forEach(shapeId -> { + JSONObject shapeLinkObj = new JSONObject(); + JSONObject fileLink = new JSONObject(); + fileLink.put("isDiff", false); + JSONObject customLink = new JSONObject(); + customLink.put("isDiff", false); + List listOfShapeCustomLink = new ArrayList<>(); + List listOfShapeFileLink = new ArrayList<>(); + JSONObject shape = elements.getJSONObject(shapeId); + if (shape.containsKey("dataAttributes")) { + JSONArray dataAttributes = shape.getJSONArray("dataAttributes"); + if (CollectionUtils.isNotEmpty(dataAttributes)) { + dataAttributes.stream().map(o -> (JSONObject) o).forEach(o -> { + if (o.containsKey("linksArray")) { + JSONArray linksArray = o.getJSONArray("linksArray"); + linksArray.stream().map(item -> (JSONObject) item).forEach(item -> { + String url = item.getString("url"); + ShapeLinkVO.Builder builder = ShapeLinkVO.Builder.createBuilder().withName(item.getString("name")).withTarget(item.getString("target")).withType(item.getString("type")).withUuid(item.getString("uuid")).withValue(item.getString("value")).withVersionId(item.getString("versionId")); + if ("file".equals(item.getString("type"))) { + String[] split = url.split("&"); + String uuidStr = Arrays.stream(split).filter(s -> s.startsWith("uuid=")).findAny().orElse(""); + String newUrl = "./w?" + uuidStr + "&teamId=" + teamId + "&cmd=com.actionsoft.apps.coe.pal_pl_repository_designer_main&sid=" + uc.getSessionId(); + ShapeLinkVO shapeLinkVO = builder.withUrl(newUrl).build(); + listOfShapeFileLink.add((JSONObject) JSONObject.toJSON(shapeLinkVO)); + } else { + ShapeLinkVO shapeLinkVO = builder.withUrl(url).build(); + listOfShapeCustomLink.add((JSONObject) JSONObject.toJSON(shapeLinkVO)); + } + }); + } + }); + } + } + fileLink.put("value", listOfShapeFileLink); + customLink.put("value", listOfShapeCustomLink); + shapeLinkObj.put("file", fileLink); + shapeLinkObj.put("custom", customLink); + mapOfShapeLink.put(shapeId, shapeLinkObj); + }); + return mapOfShapeLink; + } + } + return null; + } + + /** + * 解析模型定义信息 + * + * @param definition 模型定义信息 + * @return JSONObject + */ + private static JSONObject validateDefinition(String definition) { + if (UtilString.isEmpty(definition)) { + return null; + } + JSONObject definitionObj = null; + try { + definitionObj = JSONObject.parseObject(definition); + } catch (Exception e) { + e.printStackTrace(); + log.error("设计器版本信息对比时,模型定义信息解析失败", e); + } + return definitionObj; + } + + /** + * 获取文件属性信息 + * + * @param uc UserContext + * @param plId pal模型Id + * @return List + */ + public static List getFileAttrForCompare(UserContext uc, String plId) { + PALRepositoryModel repositoryModel = PALRepositoryCache.getCache().get(plId); + if (repositoryModel == null) { + return null; + } + // 获取属性配置信息 + List listOfMethodAttrModel = PALRepositoryAPIManager.getInstance().getValidAttributeModels(repositoryModel.getWsId(), repositoryModel.getMethodId()); + Map mapOfMethodAttrModel = listOfMethodAttrModel.stream().collect(Collectors.toMap(PALMethodAttributeModel::getKey, item -> item)); + // 获取文件属性数据 + List listOfPropertyModel = PALRepositoryPropertyCache.getPropertyByPlId(plId); + if (CollectionUtils.isNotEmpty(listOfPropertyModel)) { + List listOfAttrVO = new ArrayList<>(); + listOfPropertyModel.forEach(propertyModel -> { + if (mapOfMethodAttrModel.containsKey(propertyModel.getPropertyId()) && mapOfMethodAttrModel.get(propertyModel.getPropertyId()).getUse()) { + String id = propertyModel.getPropertyId(); + PALMethodAttributeModel methodAttributeModel = mapOfMethodAttrModel.get(id); + String name = methodAttributeModel.getNewTitle(); + Object value = propertyModel.getPropertyValue(); + String type = methodAttributeModel.getType(); + Map mapOfFileAttrValue = getFileAttrValue(uc, plId, methodAttributeModel, propertyModel); + value = mapOfFileAttrValue.get("value"); + Object compareAccord = mapOfFileAttrValue.get("compareAccord"); + AttrVO attrVO = AttrVO.Builder.createBuilder().withId(id).withName(name).withType(type).withValue(value).withIsDiff(false).withCompareAccord(compareAccord).withOrderIndex(methodAttributeModel.getIndex()).build(); + listOfAttrVO.add(attrVO); + } + }); + sortAttrVO(listOfAttrVO); // 排序 + return listOfAttrVO; + } + return null; + } + + /** + * 属性信息排序 按照属性Id的字符的自然排序 + * + * @param listOfAttrVO 属性集合 + */ + private static void sortAttrVO(List listOfAttrVO) { + if (CollectionUtils.isNotEmpty(listOfAttrVO)) { + listOfAttrVO.sort(Comparator.comparing(AttrVO::getOrderIndex)); + } + } + + private static void sortAttrVO(List listOfAttrVO, Map attrKeyAndModelMap) { + if (CollectionUtils.isNotEmpty(listOfAttrVO)) { + listOfAttrVO.sort(Comparator.comparing(o -> !attrKeyAndModelMap.containsKey(o.getId()) ? 0 : attrKeyAndModelMap.get(o.getId()).getIndex())); + } + } + + /** + * 获取文件属性信息 + * + * @param uc UserContext + * @param plId pal模型Id + * @param methodAttributeModel 属性配置信息 + * @param propertyModel 属性数据 + * @return Map + */ + public static Map getFileAttrValue(UserContext uc, String plId, PALMethodAttributeModel methodAttributeModel, PALRepositoryPropertyModel propertyModel) { + Map result = null; + switch (methodAttributeModel.getType()) { + case "relation": + result = getFileAttrOfRelation(plId, methodAttributeModel); + break; + case "awsorg": + result = getFileAttrOfAwsOrg(plId, methodAttributeModel); + break; + case "file": + result = getFileAttrUpFileList(uc, plId, methodAttributeModel); + break; + default: + result = new HashMap<>(); + result.put("value", propertyModel.getPropertyValue()); + result.put("compareAccord", sortStringContent(propertyModel.getPropertyValue())); + break; + } + return result; + } + + private static String sortStringContent(String input) { + if (!input.contains(",")) { + return input; + } + // 1. 拆分字符串 + String[] items = input.split(","); + + // 2. 对数组进行排序 + Arrays.sort(items); + + // 3. 将排序后的数组重新组合成字符串 + return String.join(",", items); + } + + /** + * 获取文件属性(附件信息) + * + * @param uc UserContext + * @param plId pal模型Id + * @param methodAttributeModel 属性配置信息 + * @return Map + */ + public static Map getFileAttrUpFileList(UserContext uc, String plId, PALMethodAttributeModel methodAttributeModel) { + JSONArray listOfFileAttrValue = new JSONArray(); + JSONArray listOfCompareAccord = new JSONArray(); + List upfileModelList = PALUpfileCache.getByPlUuid(plId); + upfileModelList = upfileModelList.stream().filter(upfileModel -> upfileModel.getType().equals("a")).filter(upfileModel -> UtilString.isEmpty(upfileModel.getShape_uuid())).filter(upfileModel -> methodAttributeModel.getKey().equals(upfileModel.getAttrId())).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(upfileModelList)) { + upfileModelList.forEach(upfileModel -> { + JSONObject valueObj = new JSONObject(); + String fileName = upfileModel.getFileName(); + String downloadUrl = getDownloadUrl(uc, upfileModel); + valueObj.put("fileName", fileName); + valueObj.put("downloadUrl", downloadUrl); + listOfFileAttrValue.add(valueObj); + String compareAccord = upfileModel.getAttrId() + "_" + upfileModel.getFileName(); + listOfCompareAccord.add(compareAccord); + }); + } + Map mapOfFileAttrValue = new HashMap<>(); + mapOfFileAttrValue.put("value", listOfFileAttrValue); + mapOfFileAttrValue.put("compareAccord", listOfCompareAccord); + return mapOfFileAttrValue; + } + + /** + * 获取文件属性(模型关联) + * + * @param plId pal模型Id + * @param methodAttributeModel 属性配置信息 + * @return Map 显示信息及对比依据 + */ + private static Map getFileAttrOfRelation(String plId, PALMethodAttributeModel methodAttributeModel) { + JSONArray listOfFileAttrValue = new JSONArray(); + JSONArray listOfCompareAccord = new JSONArray(); + List listOfRelationModel = DesignerShapeRelationCache.getListByAttrId(plId, "", methodAttributeModel.getKey()); + if (CollectionUtils.isNotEmpty(listOfRelationModel)) { + listOfRelationModel.forEach(relationModel -> { + JSONObject refObj = JSONObject.parseObject(methodAttributeModel.getRef()); + String relationTyp = refObj.containsKey("type") ? refObj.getString("type") : "shape"; + String relationFileId = relationModel.getRelationFileId(); + if ("file".equals(relationTyp)) { + listOfFileAttrValue.add(PALRepositoryCache.getCache().get(relationFileId).getName()); + listOfCompareAccord.add(relationFileId); + } else { + listOfFileAttrValue.add(relationModel.getRelationShapeText()); + listOfCompareAccord.add(relationFileId + "_" + relationModel.getRelationShapeId()); + } + }); + } + Map mapOfFileAttrValue = new HashMap<>(); + mapOfFileAttrValue.put("value", listOfFileAttrValue); + mapOfFileAttrValue.put("compareAccord", listOfCompareAccord); + return mapOfFileAttrValue; + } + + /** + * 获取文件属性(关联AWS组织) + * + * @param plId pal模型Id + * @param methodAttributeModel 属性配置信息 + * @return Map 显示信息及对比依据 + */ + private static Map getFileAttrOfAwsOrg(String plId, PALMethodAttributeModel methodAttributeModel) { + JSONArray listOfFileAttrValue = new JSONArray(); + JSONArray listOfCompareAccord = new JSONArray(); + List listOfRelationModel = DesignerShapeRelationCache.getListByAttrId(plId, "", methodAttributeModel.getKey()); + if (CollectionUtils.isNotEmpty(listOfRelationModel)) { + listOfRelationModel.forEach(relationModel -> { + if ("00000000-0000-0000-0000-000000000000".equals(relationModel.getRelationFileId()) && "00000000-0000-0000-0000-000000000000".equals(relationModel.getRelationShapeId())) { + JSONObject object = JSONObject.parseObject(relationModel.getRelationShapeText()); + listOfCompareAccord.add(object.getString("type") + "_" + object.getString("id")); + if ("department".equals(object.getString("type"))) { + DepartmentModel dept = SDK.getORGAPI().getDepartmentById(object.getString("id")); + if (dept != null) { + listOfFileAttrValue.add(dept.getName()); + } + } + if ("position".equals(object.getString("type"))) {// 岗位,先用角色代替 + RoleModel role = SDK.getORGAPI().getRoleById(object.getString("id")); + if (role != null) { + listOfFileAttrValue.add(role.getName()); + } + } + if ("user".equals(object.getString("type"))) { + UserModel user = SDK.getORGAPI().getUser(object.getString("id")); + if (user != null) { + listOfFileAttrValue.add(user.getUserName()); + } + } + if ("role".equals(object.getString("type"))) { + RoleModel role = SDK.getORGAPI().getRoleById(object.getString("id")); + if (role != null) { + listOfFileAttrValue.add(role.getName()); + } + } + } + }); + } + Map mapOfFileAttrValue = new HashMap<>(); + mapOfFileAttrValue.put("value", listOfFileAttrValue); + mapOfFileAttrValue.put("compareAccord", listOfCompareAccord); + return mapOfFileAttrValue; + } + + /** + * 获取模型附件 + * + * @param uc 用户上下文 + * @param plId 模型ID + * @return List 附件列表 + */ + public static JSONObject getFileUpFileList(UserContext uc, String plId) { + JSONObject result = new JSONObject(); + result.put("isDiff", false); + List listOfShapeFile = new ArrayList<>(); + List listOfUpFile = PALUpfileCache.getByPlUuid(plId); + if (CollectionUtils.isNotEmpty(listOfUpFile)) { + listOfUpFile.stream().filter(item -> item.getType().equals("f")).forEach(item -> { + UpFileVO upFileVO = getUpFileVO(uc, item); + listOfShapeFile.add((JSONObject) JSONObject.toJSON(upFileVO)); + }); + } + result.put("value", listOfShapeFile); + return result; + } + + /** + * 获取模型关联附件 + * + * @param uc 用户上下文 + * @param plId 模型ID + * @return List 附件列表 + */ + public static JSONObject getFileRelationUpFileList(UserContext uc, String plId) { + JSONObject result = new JSONObject(); + result.put("isDiff", false); + List listOfShapeFile = new ArrayList<>(); + DesignerShapeRelationDao dao = new DesignerShapeRelationDao(); + List listOfShapeRelation = dao.getModelListByFileId(plId); + if (CollectionUtils.isNotEmpty(listOfShapeRelation)) { + listOfShapeRelation.stream().filter(item -> UtilString.isEmpty(item.getRelationShapeId())).forEach(item -> { + String relationFileId = item.getRelationFileId(); + String relationShapeId = item.getRelationShapeId(); + List listOfUpFile = PALUpfileCache.getByPlUuid(relationFileId); + if (UtilString.isEmpty(relationShapeId)) { // 关联的文件 获取关联文件的附件 + listOfUpFile = listOfUpFile.stream().filter(u -> u.getType().equals("f")).collect(Collectors.toList()); + } else { // 关联的形状 获取关联的形状附件 + listOfUpFile = listOfUpFile.stream().filter(u -> u.getType().equals("s")).filter(u -> u.getShape_uuid().equals(item.getRelationShapeId())).collect(Collectors.toList()); + } + if (CollectionUtils.isNotEmpty(listOfUpFile)) { + listOfUpFile.forEach(u -> { + UpFileVO upFileVO = getUpFileVO(uc, u); + listOfShapeFile.add((JSONObject) JSONObject.toJSON(upFileVO)); + }); + } + }); + } + result.put("value", listOfShapeFile); + return result; + } + + /** + * 比对文件属性 + * + * @param versionData 比对的版本 + * @param curData 当前使用版本 + */ + public static void compareFileAttr(JSONObject versionData, JSONObject curData) { + JSONArray hisShapeAttr = versionData.getJSONArray("fileAttr"); + JSONArray curShapeAttr = curData.getJSONArray("fileAttr"); + compareAttr(hisShapeAttr, curShapeAttr); + } + + /** + * 比对形状属性 + * + * @param versionData 比对的版本 + * @param curData 当前使用版本 + * @return 返回属性有差异的形状ID + */ + public static Set compareShapeAttr(JSONObject versionData, JSONObject curData) { + JSONObject hisShapeAttr = versionData.getJSONObject("shapeAttr"); + JSONObject curShapeAttr = curData.getJSONObject("shapeAttr"); + return compareAttr(hisShapeAttr, curShapeAttr); + } + + /** + * 比对属性 + * + * @param hisShapeAttr 待比对的版本 + * @param curShapeAttr 当前使用版本 + * @return 返回属性有差异的形状ID + */ + private static Set compareAttr(JSONObject hisShapeAttr, JSONObject curShapeAttr) { + Set setOfShapeId = new HashSet<>(); + if (hisShapeAttr != null && curShapeAttr != null) { + // 遍历当前形状属性 + curShapeAttr.keySet().forEach(curShapeId -> { + // 获取当前形状属性集合 + JSONArray curShapeAttrs = curShapeAttr.getJSONArray(curShapeId); + if (curShapeAttrs.size() > 0) { + for (int i = 0; i < curShapeAttrs.size(); i++) { + JSONObject curShapeAttrItem = curShapeAttrs.getJSONObject(i); + String curType = curShapeAttrItem.getString("type"); + Object compareAccord = curShapeAttrItem.get("compareAccord"); + String attrId = curShapeAttrItem.getString("id"); + // 判断对比的版本数据是否存在当前形状 不存在不用对比 + if (hisShapeAttr.containsKey(curShapeId)) { + JSONArray hisShapeAttrItem = hisShapeAttr.getJSONArray(curShapeId); + Map mapOfShapeAttrItem = new HashMap<>(); + for (int j = 0; j < hisShapeAttrItem.size(); j++) { + JSONObject hisItem = hisShapeAttrItem.getJSONObject(j); + String hisType = hisItem.getString("type"); + String hisAttrId = hisItem.getString("id"); + Object hisCompareAccord = hisItem.get("compareAccord"); + mapOfShapeAttrItem.put(hisType + "_" + hisAttrId, hisCompareAccord); + } + if (mapOfShapeAttrItem.containsKey(curType + "_" + attrId)) { + Object hisCompareAccord = mapOfShapeAttrItem.get(curType + "_" + attrId); + boolean isDiff = checkDiffCompareAccord(curType, hisCompareAccord, compareAccord); + if (isDiff) { + curShapeAttrItem.put("isDiff", true); + curShapeAttrs.set(i, curShapeAttrItem); + setOfShapeId.add(curShapeId); + } + } + } + } + } + }); + } + return setOfShapeId; + } + + /** + * 比对属性 + * + * @param hisShapeAttr 待比对的版本 + * @param curShapeAttr 当前使用版本 + * @return 返回属性有差异的形状ID + */ + private static void compareAttr(JSONArray hisShapeAttr, JSONArray curShapeAttr) { + if (hisShapeAttr != null && curShapeAttr != null) { + Map mapOfAttrItem = new HashMap<>(); + for (Object hisO : hisShapeAttr) { + JSONObject hisItem = (JSONObject) JSONObject.toJSON(hisO); + String hisType = hisItem.getString("type"); + String hisAttrId = hisItem.getString("id"); + Object hisCompareAccord = hisItem.get("compareAccord"); + mapOfAttrItem.put(hisType + "_" + hisAttrId, hisCompareAccord); + } + for (int i = 0; i < curShapeAttr.size(); i++) { + JSONObject curShapeAttrItem = curShapeAttr.getJSONObject(i); + String curType = curShapeAttrItem.getString("type"); + Object compareAccord = curShapeAttrItem.get("compareAccord"); + String attrId = curShapeAttrItem.getString("id"); + // 判断对比的版本数据是否存在当前形状 不存在不用对比 + if (mapOfAttrItem.containsKey(curType + "_" + attrId)) { + Object hisCompareAccord = mapOfAttrItem.get(curType + "_" + attrId); + boolean isDiff = checkDiffCompareAccord(curType, hisCompareAccord, compareAccord); + if (isDiff) { + curShapeAttrItem.put("isDiff", true); + curShapeAttr.set(i, curShapeAttrItem); + } + } + } + } + } + + private static boolean checkDiffCompareAccord(String type, Object hisCompareAccord, Object curCompareAccord) { + boolean isDiff = false; + if ("relation".equals(type) || "awsorg".equals(type) || "file".equals(type)) { + if (hisCompareAccord instanceof JSONArray && curCompareAccord instanceof JSONArray) { + if (((JSONArray) hisCompareAccord).size() == ((JSONArray) curCompareAccord).size()) { + // 排序 + hisCompareAccord = sortJSONArrayOfCompareAccord((JSONArray) hisCompareAccord); + curCompareAccord = sortJSONArrayOfCompareAccord((JSONArray) curCompareAccord); + for (int i = 0; i < ((JSONArray) hisCompareAccord).size(); i++) { + if (!((JSONArray) hisCompareAccord).get(i).equals(((JSONArray) curCompareAccord).get(i))) { + isDiff = true; + break; + } + } + } else { + isDiff = true; + } + } + } else { + isDiff = !hisCompareAccord.equals(curCompareAccord); + } + return isDiff; + } + + private static JSONArray sortJSONArrayOfCompareAccord(JSONArray compareAccord) { + String[] array = new String[compareAccord.size()]; + for (int i = 0; i < compareAccord.size(); i++) { + array[i] = compareAccord.getString(i); + } + Arrays.sort(array); + JSONArray result = new JSONArray(); + Collections.addAll(result, array); + return result; + } + + public static List compareNodeAndLinkInfo(JSONObject versionData, JSONObject curDate, Set setOfShapeIdInfoDiff) { + String compareDefinition = versionData.getString("definition"); + JSONObject compareDefineObj = JSONObject.parseObject(compareDefinition); + String curDefinition = curDate.getString("definition"); + JSONObject curDefineObj = JSONObject.parseObject(curDefinition); + + JSONObject compareElements = compareDefineObj.getJSONObject("elements"); + JSONObject elements = curDefineObj.getJSONObject("elements"); + List diffNodeVOList = new ArrayList<>(); + if (compareElements != null && elements != null) { + elements.keySet().forEach(key -> { + JSONObject curElement = elements.getJSONObject(key); + List types = predicateEleDiffType(compareElements, curElement, setOfShapeIdInfoDiff); + DiffNodeVO diffNodeVO = DiffNodeVO.Builder.create().withId(key).withType(types).build(); + diffNodeVOList.add(diffNodeVO); + }); + // 节点删除 + compareElements.keySet().forEach(key -> { + if (!elements.containsKey(key)) { + // 节点删除 + List types = new ArrayList<>(); + types.add(DiffNodeTypeEnum.DELETE.getCode()); + DiffNodeVO diffNodeVO = DiffNodeVO.Builder.create().withId(key).withType(types).build(); + diffNodeVOList.add(diffNodeVO); + } + }); + } + + return diffNodeVOList; + } + + public static List predicateEleDiffType(JSONObject compareElements, JSONObject curElement, Set setOfShapeIdInfoDiff) { + + List types = null; + String curEleName = curElement.getString("name"); + + if ("linker".equals(curEleName)) { + types = predicateLinkerDiffType(compareElements, curElement); + } else { + types = predicateNodeDiffType(compareElements, curElement, setOfShapeIdInfoDiff); + } + return types; + } + + private static List predicateLinkerDiffType(JSONObject compareElements, JSONObject curElement) { + List types = new ArrayList<>(); + String curEleId = curElement.getString("id"); // 连线Id + // 对比版本中不存在 视为新增 + if (!compareElements.containsKey(curEleId)) { + types.add(DiffNodeTypeEnum.ADD.getCode()); + return types; + } + // 连线两端的节点 与对比版本中相同连线ID的两端节点ID 不一致 视为新增连线 + JSONObject fromObj = curElement.getJSONObject("from"); + String fromShapeId = fromObj.getString("id"); + fromShapeId = UtilString.isEmpty(fromShapeId) ? "" : fromShapeId; + JSONObject toObj = curElement.getJSONObject("to"); + String toShapeId = toObj.getString("id"); + toShapeId = UtilString.isEmpty(toShapeId) ? "" : toShapeId; + + JSONObject compareLinker = compareElements.getJSONObject(curEleId); + JSONObject compareFromObj = compareLinker.getJSONObject("from"); + String compareFromShapeId = compareFromObj.getString("id"); + compareFromShapeId = UtilString.isEmpty(compareFromShapeId) ? "" : compareFromShapeId; + JSONObject compareToObj = compareLinker.getJSONObject("to"); + String compareToShapeId = compareToObj.getString("id"); + compareToShapeId = UtilString.isEmpty(compareToShapeId) ? "" : compareToShapeId; + + if (!fromShapeId.equals(compareFromShapeId) || !toShapeId.equals(compareToShapeId)) { + types.add(DiffNodeTypeEnum.ADD.getCode()); + } + return types; + } + + private static List predicateNodeDiffType(JSONObject compareElements, JSONObject curElement, Set setOfShapeIdInfoDiff) { + List types = new ArrayList<>(); + String curEleId = curElement.getString("id"); + // 对比版本中不存在 视为新增 + if (!compareElements.containsKey(curEleId)) { + types.add(DiffNodeTypeEnum.ADD.getCode()); + return types; + } + // 形状位置 + JSONObject curProps = curElement.getJSONObject("props"); + double curX = curProps.getDoubleValue("x"); + double curY = curProps.getDoubleValue("y"); + JSONObject compareEle = compareElements.getJSONObject(curEleId); + JSONObject compareProps = compareEle.getJSONObject("props"); + double compareX = compareProps.getDoubleValue("x"); + double compareY = compareProps.getDoubleValue("y"); + if (curX != compareX || curY != compareY) { + types.add(DiffNodeTypeEnum.POSITION.getCode()); + } + // 形状名称、样式 + String text = curElement.getString("text"); + String compareText = compareEle.getString("text"); + if (!text.equals(compareText)) { + types.add(DiffNodeTypeEnum.STYLE.getCode()); + } + String curShowConfig = ""; + if (curElement.containsKey("dataAttributes")) { + JSONArray dataAttributes = curElement.getJSONArray("dataAttributes"); + for (int i = 0; i < dataAttributes.size(); i++) { + JSONObject dataAttribute = dataAttributes.getJSONObject(i); + if (dataAttribute.containsKey("dataShowConfig")) { + curShowConfig = dataAttribute.getJSONObject("dataShowConfig").toJSONString(); + } + } + } + String compareShowConfig = ""; + if (compareEle.containsKey("dataAttributes")) { + JSONArray compareDataAttributes = compareEle.getJSONArray("dataAttributes"); + for (int i = 0; i < compareDataAttributes.size(); i++) { + JSONObject compareDataAttribute = compareDataAttributes.getJSONObject(i); + if (compareDataAttribute.containsKey("dataShowConfig")) { + compareShowConfig = compareDataAttribute.getJSONObject("dataShowConfig").toJSONString(); + } + } + } + if (!curShowConfig.equals(compareShowConfig) && !types.contains(DiffNodeTypeEnum.STYLE.getCode())) { + types.add(DiffNodeTypeEnum.STYLE.getCode()); + } + + // 节点信息 + if (setOfShapeIdInfoDiff.contains(curEleId)) { + types.add(DiffNodeTypeEnum.INFO.getCode()); + } + return types; + } + + /** + * 对比形状文件 + * + * @param versionData 待对比的数据 + * @param curData 当前数据 + */ + public static Set compareShapeFile(JSONObject versionData, JSONObject curData) { + JSONObject hisShapeUpFile = versionData.getJSONObject("shapeUpFile"); + JSONObject curShapeUpFile = curData.getJSONObject("shapeUpFile"); + return compareFileIsDiff(hisShapeUpFile, curShapeUpFile); + } + + /** + * 对比形状关联文件 + * + * @param versionData 待对比的数据 + * @param curData 当前数据 + */ + public static Set compareShapeRelationFile(JSONObject versionData, JSONObject curData) { + JSONObject hisShapeRelationFile = versionData.getJSONObject("shapeRelationUpFile"); + JSONObject curShapeRelationFile = curData.getJSONObject("shapeRelationUpFile"); + return compareFileIsDiff(hisShapeRelationFile, curShapeRelationFile); + } + + private static Set compareFileIsDiff(JSONObject hisShapeUpFile, JSONObject curShapeUpFile) { + Set setOfShapeId = new HashSet<>(); + if (hisShapeUpFile != null && curShapeUpFile != null) { + curShapeUpFile.keySet().forEach(key -> { + JSONObject curShapeUpFileObj = curShapeUpFile.getJSONObject(key); + JSONArray curValue = curShapeUpFileObj.getJSONArray("value"); + if (hisShapeUpFile.containsKey(key)) { + JSONObject hisShapeUpFileObj = hisShapeUpFile.getJSONObject(key); + JSONArray hisValue = hisShapeUpFileObj.getJSONArray("value"); + if (predicateUpFileISDiff(hisValue, curValue)) { + curShapeUpFileObj.put("isDiff", true); + setOfShapeId.add(key); + } + } + }); + } + return setOfShapeId; + } + + /** + * 判断文件是否存在差异 判断依据:文件数量 文件Id + * + * @param hisValue 待对比的数据 + * @param curValue 当前数据 + * @return boolean + */ + private static boolean predicateUpFileISDiff(JSONArray hisValue, JSONArray curValue) { + boolean isDiff = hisValue.size() != curValue.size(); + Map mapOfHisValue = new HashMap<>(); + for (int i = 0; i < hisValue.size(); i++) { + JSONObject hisValItem = hisValue.getJSONObject(i); + mapOfHisValue.put(hisValItem.getString("fileName"), hisValItem); + } + for (int i = 0; i < curValue.size(); i++) { + JSONObject curValItem = curValue.getJSONObject(i); + if (!mapOfHisValue.containsKey(curValItem.getString("fileName"))) { + isDiff = true; + break; + } + } + return isDiff; + } + + public static Set compareShapeLink(JSONObject versionData, JSONObject curData) { + Set setOfShapeId = new HashSet<>(); + JSONObject hisShapeLink = versionData.getJSONObject("shapeLink"); + JSONObject curShapeLink = curData.getJSONObject("shapeLink"); + if (hisShapeLink != null && curShapeLink != null) { + curShapeLink.keySet().forEach(key -> { + JSONObject curShapeLinkObj = curShapeLink.getJSONObject(key); + JSONObject fileLinkObj = curShapeLinkObj.getJSONObject("file"); + JSONArray fileLinkValue = fileLinkObj.getJSONArray("value"); + JSONObject customLinkObj = curShapeLinkObj.getJSONObject("custom"); + JSONArray customLinkValue = customLinkObj.getJSONArray("value"); + if (hisShapeLink.containsKey(key)) { + JSONObject hisShapeLinkObj = hisShapeLink.getJSONObject(key); + JSONObject hisFileLinkObj = hisShapeLinkObj.getJSONObject("file"); + JSONArray hisFileLinkValue = hisFileLinkObj.getJSONArray("value"); + JSONObject hisCustomLinkObj = hisShapeLinkObj.getJSONObject("custom"); + JSONArray hisCustomLinkValue = hisCustomLinkObj.getJSONArray("value"); + + // 比较文件链接 + if (!fileLinkValue.toJSONString().equals(hisFileLinkValue.toJSONString())) { + fileLinkObj.put("isDiff", true); + setOfShapeId.add(key); + } + // 比较自定义链接 + if (!customLinkValue.toJSONString().equals(hisCustomLinkValue.toJSONString())) { + customLinkObj.put("isDiff", true); + setOfShapeId.add(key); + } + } + }); + } + return setOfShapeId; + } + + /** + * 比对模型附件 + * + * @param versionData 待对比的数据 + * @param curData 当前数据 + */ + public static void compareFileUpFileList(JSONObject versionData, JSONObject curData) { + JSONObject hisFileUpFileObj = versionData.getJSONObject("fileUpFile"); + JSONArray hisValue = hisFileUpFileObj.getJSONArray("value"); + JSONObject curFileUpFileObj = curData.getJSONObject("fileUpFile"); + JSONArray curValue = curFileUpFileObj.getJSONArray("value"); + if (predicateUpFileISDiff(hisValue, curValue)) { + curFileUpFileObj.put("isDiff", true); + } + } + + /** + * 比对模型关联附件 + * + * @param versionData 待对比的数据 + * @param curData 当前数据 + */ + public static void compareFileRelationUpFileList(JSONObject versionData, JSONObject curData) { + JSONObject hisFileUpFileObj = versionData.getJSONObject("fileRelationUpFile"); + JSONArray hisValue = hisFileUpFileObj.getJSONArray("value"); + JSONObject curFileUpFileObj = curData.getJSONObject("fileRelationUpFile"); + JSONArray curValue = curFileUpFileObj.getJSONArray("value"); + if (predicateUpFileISDiff(hisValue, curValue)) { + curFileUpFileObj.put("isDiff", true); + } + } + + /** + * 获取 版本对比 map参数 + * + * @param compareVerId 对比模型版本ID + * @param versionData 对比版本的模型数据 + * @param curId 当前模型版本ID + * @param curData 当前模型数据 + * @param ifHideUI 是否隐藏属性等UI + */ + public static Map queryDesignerVersionCompareMap(String wsId, String methodId, String fileName, String compareVerId, JSONObject versionData, String curId, JSONObject curData, boolean isProcessExec, boolean ifHideUI) { + Map macroLibraries = new HashMap<>(); + + // 节点与连线对比信息 + Set setOfShapeIdInfoDiff = new HashSet<>(); + if (!ifHideUI) { + // 对比形状属性差异 + Set setOfShapeIdAttrDiff = compareShapeAttr(versionData, curData); + // 对比文件属性 + compareFileAttr(versionData, curData); + // 对比形状附件 + Set setOfShapeIdFileDiff = compareShapeFile(versionData, curData); + // 对比形状关联附件 + Set setOfShapeIdRelationFileDiff = compareShapeRelationFile(versionData, curData); + // 对比形状链接 + Set setOfShapeIdLinkDiff = compareShapeLink(versionData, curData); + // 对比文件附件 + compareFileUpFileList(versionData, curData); + // 对比文件关联附件 + compareFileRelationUpFileList(versionData, curData); + setOfShapeIdInfoDiff.addAll(setOfShapeIdAttrDiff); + setOfShapeIdInfoDiff.addAll(setOfShapeIdFileDiff); + setOfShapeIdInfoDiff.addAll(setOfShapeIdRelationFileDiff); + setOfShapeIdInfoDiff.addAll(setOfShapeIdLinkDiff); + } + macroLibraries.put("versionData", versionData); + macroLibraries.put("curData", curData); + List listOfDiffNodeVO = compareNodeAndLinkInfo(versionData, curData, setOfShapeIdInfoDiff); + macroLibraries.put("diffNode", JSON.toJSON(listOfDiffNodeVO)); + + PALRepositoryModel compareModel = PALRepositoryCache.getCache().get(compareVerId); + Map mapOfLeft = getRelationShapeInfo(compareModel, versionData.getString("definition")); + macroLibraries.put("leftOfRelationShapes", mapOfLeft.get("relationShapes")); + PALRepositoryModel curModel = PALRepositoryCache.getCache().get(curId); + Map mapOfRight = getRelationShapeInfo(curModel, curData.getString("definition")); + macroLibraries.put("rightOfRelationShapes", mapOfRight.get("relationShapes")); + // 版本对比页面与梳理到执行流程对比页面共用 以此进行区分 方便页面屏蔽一些逻辑与数据 + macroLibraries.put("isProcessExec", isProcessExec); + macroLibraries.put("ifHideUI", ifHideUI); + JSONObject methodIcon = PALMethodUtil.getPALMethodIconById(methodId, wsId); + macroLibraries.put("methodIcon", methodIcon); + macroLibraries.put("methodId", methodId); + macroLibraries.put("fileName", fileName); + return macroLibraries; + } + + public static Map getRelationShapeInfo(String plId) { + PALRepositoryModel plModel = PALRepositoryCache.getCache().get(plId); + String define = PALRepositoryQueryAPIManager.getInstance().getProcessDefinition(null, plId); + return getRelationShapeInfo(plModel, define); + } + + public static Map getRelationShapeInfo(PALRepositoryModel plModel, String define) { + Map mapOfResult = new HashMap<>(); + JSONObject relationShapeIds = new JSONObject(); + JSONObject relationShapeModels = new JSONObject(); + if (plModel == null || UtilString.isEmpty(define)) { + mapOfResult.put("relationShapes", relationShapeIds); + mapOfResult.put("relationShapeModels", relationShapeModels); + return mapOfResult; + } + List> elements = ShapeUtil.getShapeJson(define, plModel.getId(), plModel.getName()); + if (!elements.isEmpty()) { + for (Map element : elements) { + String elementId = element.containsKey("id") ? element.get("id").toString() : ""; + if (!UtilString.isEmpty(elementId)) { + List modelList = DesignerShapeRelationCache.getListByShapeId(plModel.getId(), elementId); + // relation类型数据去重 + List tempList = new ArrayList<>(); + Set ids = new HashSet<>(); + for (DesignerShapeRelationModel model : modelList) { + if ("00000000-0000-0000-0000-000000000000".equals(model.getRelationFileId()) && "00000000-0000-0000-0000-000000000000".equals(model.getRelationShapeId())) { + tempList.add(model); + continue; + } + String id = model.getFileId() + model.getShapeId() + model.getAttrId() + model.getRelationFileId() + model.getRelationShapeId(); + if (!ids.contains(id)) { + tempList.add(model); + ids.add(id); + } + } + modelList = tempList; + for (DesignerShapeRelationModel shapeRelationModel : modelList) { + PALRepositoryModel relationPalModel = PALRepositoryCache.getCache().get(shapeRelationModel.getRelationFileId()); + if (relationPalModel != null) { + relationShapeIds.put(shapeRelationModel.getRelationShapeId(), shapeRelationModel); + String key = shapeRelationModel.getShapeId() + "_" + shapeRelationModel.getAttrId(); + if (relationShapeModels.containsKey(key)) { + String value = relationShapeModels.getString(key) + "|" + shapeRelationModel.getRelationShapeText(); + relationShapeModels.put(key, value); + } else { + relationShapeModels.put(key, shapeRelationModel.getRelationShapeText()); + } + } + } + } + } + } + mapOfResult.put("relationShapes", relationShapeIds); + mapOfResult.put("relationShapeModels", relationShapeModels); + return mapOfResult; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/AttrVO.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/AttrVO.java new file mode 100644 index 00000000..e9409bd6 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/AttrVO.java @@ -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); + } + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/DiffNodeVO.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/DiffNodeVO.java new file mode 100644 index 00000000..70cd038a --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/DiffNodeVO.java @@ -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 type; // 节点或者连线变化类型(多个,连线只有新增) + + private DiffNodeVO(Builder builder) { + this.id = builder.id; + this.type = builder.type; + } + + public String getId() { + return id; + } + + public List getType() { + return type; + } + + public static final class Builder { + private String id; + private List type; + + private Builder() { + } + + public static Builder create() { + return new Builder(); + } + + public Builder withId(String id) { + this.id = id; + return this; + } + + public Builder withType(List type) { + this.type = type; + return this; + } + + public DiffNodeVO build() { + return new DiffNodeVO(this); + } + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/ShapeLinkVO.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/ShapeLinkVO.java new file mode 100644 index 00000000..a337d7a9 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/ShapeLinkVO.java @@ -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); + } + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/UpFileVO.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/UpFileVO.java new file mode 100644 index 00000000..8b9ea19d --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/UpFileVO.java @@ -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); + } + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/VersionListVO.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/VersionListVO.java new file mode 100644 index 00000000..f07aff54 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/vo/VersionListVO.java @@ -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); + } + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/web/CoeDesignerVersionWeb.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/web/CoeDesignerVersionWeb.java new file mode 100644 index 00000000..f111805d --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/web/CoeDesignerVersionWeb.java @@ -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 versionListVoList = new ArrayList<>(); + List historyVersionListVoList = new ArrayList<>(); + PALRepositoryModel palModel = PALRepositoryCache.getCache().get(id); + if (palModel != null) { + // 维护pal模型Id与bpm平台模型Id映射 + Map mapOfProcessDefId = new HashMap<>(); + List 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 macroLibraries = queryDesignerVersionCompareMap(versionCompareDTO); + return HtmlPageTemplate.merge(CoEConstant.APP_ID, CoeDesignerConstant.DESIGNER_VERSION_COMPARE_PAGE, macroLibraries); + } + + /** + * 获取 版本对比 map参数 + * + * @param versionCompareDTO 版本对比参数 + */ + private Map 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); + } + +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/model/CoeProcessLevelCorrelateModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/model/CoeProcessLevelCorrelateModel.java index 01af783b..119fcdd7 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/model/CoeProcessLevelCorrelateModel.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/model/CoeProcessLevelCorrelateModel.java @@ -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; + } } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/cache/PALUpfileCache.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/cache/PALUpfileCache.java new file mode 100644 index 00000000..9840a031 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/cache/PALUpfileCache.java @@ -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 { + + 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 getByPlUuid(String plUuid) { + List 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 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 iter = getCache().getByIndex(PALUpfileCacheIndex1.class, plUuid); + while (iter.hasNext()) { + UpfileModel next = iter.next(); + getCache().remove(next.getUuid()); + } + } + + public static List getByPlUuidAndType(String plUuid, String type) { + List 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 getByPlUuidAndShapeIds(String plUuid, List shapeIds) { + if (UtilString.isEmpty(plUuid) || shapeIds == null || shapeIds.isEmpty()) { + return Collections.emptyList(); + } + List 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 getByPlUuidAndShapeId(String plUuid, String shapeId) { + if (UtilString.isEmpty(plUuid) || UtilString.isEmpty(shapeId)) { + return Collections.emptyList(); + } + List 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 t) { + UpFileDao upFileDao = new UpFileDao(); + List _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 { + @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()); + } + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/cache/PALUpfileCacheIndex1.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/cache/PALUpfileCacheIndex1.java new file mode 100644 index 00000000..193877a3 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/cache/PALUpfileCacheIndex1.java @@ -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 { + @Override + public String key(UpfileModel upfileModel) { + return upfileModel.getPl_uuid(); + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/constant/CoeFileConstant.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/constant/CoeFileConstant.java index cbfeb0d3..655a0d94 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/constant/CoeFileConstant.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/constant/CoeFileConstant.java @@ -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"; // 属性附件 } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/dao/UpFileDao.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/dao/UpFileDao.java index 58fd8e63..89e1e906 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/dao/UpFileDao.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/dao/UpFileDao.java @@ -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 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(); + } } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/model/UpfileModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/model/UpfileModel.java index 2a9a5d78..7923c1b0 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/model/UpfileModel.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/model/UpfileModel.java @@ -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; + } } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/util/CoeUpFileUtil.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/util/CoeUpFileUtil.java new file mode 100644 index 00000000..e591a743 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/util/CoeUpFileUtil.java @@ -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 附件上传工具类 处理设计器中 文件附件、形状附件
+ * 属性附件参考: {@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 +// *
+//	 *     文件附件:tmp/upfile/uuid/fileName
+//	 *     形状附件:tmp/upfile/uuid_shapeId/fileName
+//	 *     文件属性附件:tmp/attr_upfile/uuid_attrId/fileName
+//	 *     形状属性附件:tmp/attr_upfile/uuid_shapeId_attrId/fileName
+//	 * 
+// * +// * @param model 上传文件模型 +// */ +// public static DCContext getTmpUpFileDCContext(UpfileModel model) { +// return getTmpUpFileDCContext(model.getType(), model.getPl_uuid(), model.getShape_uuid(), model.getAttrId(), model.getFileName()); +// } +// +// /** +// * 获取tmp目录对应DCContext +// *
+//	 *     文件附件:tmp/upfile/uuid/fileName
+//	 *     形状附件:tmp/upfile/uuid_shapeId/fileName
+//	 *     文件属性附件:tmp/attr_upfile/uuid_attrId/fileName
+//	 *     形状属性附件:tmp/attr_upfile/uuid_shapeId_attrId/fileName
+//	 * 
+// */ +// 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 shapeAttachmentMap, JSONArray relationAttachmentList, Map relationShapeAttachmentMap) { +// List 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 relationModels = DesignerShapeRelationCache.getListByFileId(plId); +// Map> relationModelsMap = relationModels.stream().collect(Collectors.groupingBy(item -> UtilString.isEmpty(item.getShapeId()))); +// // 关联附件列表 +// List fileRelationModels = relationModelsMap.getOrDefault(true, Collections.emptyList()); +// List shapeRelationModels = relationModelsMap.getOrDefault(false, Collections.emptyList()); +// +// // 文件关联附件组装 +// List relFileUpfileModels = getRelationAttachmentList(wsId, methodId, fileRelationModels); +// relFileUpfileModels.forEach(model -> relationAttachmentList.add(wrapperAttachmentObj(uc, model))); +// // 形状关联附件组装 +// Map> shapeRelationModelsMap = shapeRelationModels.stream().filter(item -> UtilString.isNotEmpty(item.getShapeId())).collect(Collectors.groupingBy(DesignerShapeRelationModel::getShapeId)); +// for (Map.Entry> entry : shapeRelationModelsMap.entrySet()) { +// String shapeId = entry.getKey(); +// List models = entry.getValue(); +// List 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 getRelationAttachmentList(String wsId, String methodId, List relationModels) { +// List relUpfileModels = new ArrayList<>(); +// // attrKey , relationType[ref中的type] +// Map relationTypeMap = new HashMap<>(); +// // 获取属性列表 +// List 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 useRelUpFileList = PALUpfileCache.getByPlUuid(uesRelPlModel.getId()); +// if (!useRelUpFileList.isEmpty()) { +// relUpfileModels.addAll(useRelUpFileList); +// } +// } +// } else { +// List useRelUpFileList = PALUpfileCache.getByPlUuidAndShapeId(relationModel.getRelationFileId(), relationModel.getRelationShapeId()); +// if (!useRelUpFileList.isEmpty()) { +// relUpfileModels.addAll(useRelUpFileList); +// } +// } +// } +// return relUpfileModels; +// } + +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/util/MethodAttrUpFileUtil.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/util/MethodAttrUpFileUtil.java new file mode 100644 index 00000000..d6e989b3 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/upfile/util/MethodAttrUpFileUtil.java @@ -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 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; + } +// +// /** +// * 获取属性附件临时目录 +// *
+//	 *     文件属性附件:tmp/attr_upfile/uuid_attrId/fileName
+//	 *     形状属性附件:tmp/attr_upfile/uuid_shapeId_attrId/fileName
+//	 * 
+// * +// * @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; +// } +// +// /** +// * 获取属性附件临时目录 +// *
+//	 *     文件属性附件:tmp/attr_upfile/uuid_attrId/fileName
+//	 *     形状属性附件:tmp/attr_upfile/uuid_shapeId_attrId/fileName
+//	 * 
+// * +// * @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); +// } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/web/CoeProcessLevelWeb.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/web/CoeProcessLevelWeb.java index 52f1b75c..40d07d12 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/web/CoeProcessLevelWeb.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/web/CoeProcessLevelWeb.java @@ -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 { @Override @@ -13221,4 +13255,6 @@ public class CoeProcessLevelWeb extends ActionWeb { } + + } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/plugin/Plugins.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/plugin/Plugins.java index adb18440..3a8cd488 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/plugin/Plugins.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/plugin/Plugins.java @@ -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中自定义的查询条件")); diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/util/CoeDcUtil.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/util/CoeDcUtil.java new file mode 100644 index 00000000..d240f879 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/util/CoeDcUtil.java @@ -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}
+ * 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}
+ * 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}
+ * 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}
+ * 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}
+ * DC判空,且判断DC文件是否存在,不存在则返回 null
+ * 携带前缀: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); + } + +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/util/HighSecurityUtil.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/util/HighSecurityUtil.java index 8d507dd8..fbf6c66b 100644 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/util/HighSecurityUtil.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/util/HighSecurityUtil.java @@ -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 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 getSecurityInfoMap() { + Map map = new HashMap<>(); + if (isON()) { + // 获取平台的对象秘级参数设置 + HashMap securityMap = getObjSecurityMap(); + // 获取PAL应用参数密级颜色设置 + JSONObject highSecurityFontStyle = getHighSecurityFontStyle(); + Set> entries = securityMap.entrySet(); + for (Map.Entry 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; + } } diff --git a/com.actionsoft.apps.coe.pal/template/page/console.m.process.design.bpmn.designer.htm b/com.actionsoft.apps.coe.pal/template/page/console.m.process.design.bpmn.designer.htm new file mode 100644 index 00000000..d0107caa --- /dev/null +++ b/com.actionsoft.apps.coe.pal/template/page/console.m.process.design.bpmn.designer.htm @@ -0,0 +1,1708 @@ + + + + + <#processName> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <#processdeftpl_js> + + + + + +

+ +
+ + + + +
+
+
+ +
+
+
+
+ + +
Arial
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+ +
+ + + + + + + + + +
+
+
+
+ +
+
V<#processVersion>
+
<#versionName>
+
+ +
+
+ +
+ + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+ + +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ : +
+
+
+ : +
+
+
+
+
+ +
+ : +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
X:
+
+
:
+
+
+
Y:
+
+
:
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
:
+
+
+
:
+
+
+
:
+
+
+
+
+ +
+
:
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
:
+ +
+
:
+ +
+
:
+
+
+
+
+
+
+
+
    +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
...
+
+
+
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + +
+
+
+
+ + + Alt + + + Ctrl + + + Ctrl + < , Ctrl + > + + + Ctrl + A + + + Esc + + + T + + + I + + + L + +   + + + (←↑↓→) + + + Ctrl + (←↑↓→) + + + Ctrl + + +   + + Ctrl + Z + + + Ctrl + Y + +   + + Ctrl + X + + + Ctrl + C + + + Ctrl + V + + + Ctrl + D + + + Ctrl + Shift + B + + + Delete, Backspace + +   + + Ctrl + ] + + + Ctrl + [ + + + Ctrl + Shift + ] + + + Ctrl + Shift + [ + +   + + Ctrl + L + + + Ctrl + Shift + L + +   + + Ctrl + G + + + Ctrl + Shift + G + +   + + + + + + Ctrl + B + + + Ctrl + I + + + Ctrl + U + + + Ctrl + Enter + +
+
+
+
+ +
+
+
+

+ 您可以把使用中遇到的问题功能的建议评论等发送给我们我们迫切希望得到您有价值的反馈有您的反馈我们会做的更好!

: +

+ + + + +
+
+ +
+
+ + + +
+
+
+
+
    +
  • + + +
    +
  • +
  • + + +
    +
  • +
  • + + +
    +
  • +
+ + + + +
+
+
+
  +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+

+
+
+
+
+ + +
+
+
+
    +
  • +
  • +
  • +
+
+
+
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + + + + + + +
+
+
+
<#checkoutusername>
+
<#checkouttime>,
+
+
+
+ + + + + + + + + + + + + + + + + + + + diff --git a/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.graph.versionCompare.htm b/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.graph.versionCompare.htm new file mode 100644 index 00000000..fbcad69d --- /dev/null +++ b/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.graph.versionCompare.htm @@ -0,0 +1,280 @@ + + + + + <#fileName> + + + + + + + + + + + + + + + +
+
+
+ + + +
+
+
+ + +
+
+ +
+
+ +
+
+
+ +
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+
+
+ +
+ +
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.htm b/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.htm index 0334c291..7ec90139 100755 --- a/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.htm +++ b/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.htm @@ -8,6 +8,7 @@ +