package com.artfess.bpm.util; import java.io.IOException; import java.lang.reflect.Method; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.namespace.QName; import com.artfess.base.feign.SystemConfigFeignService; import org.apache.commons.lang.StringUtils; import org.springframework.security.core.GrantedAuthority; import org.springframework.util.Assert; import org.w3c.dom.Element; import com.fasterxml.jackson.databind.node.ObjectNode; import com.artfess.base.exception.BaseException; import com.artfess.base.feign.UCFeignService; import com.artfess.base.util.AppUtil; import com.artfess.base.util.BeanUtils; import com.artfess.base.util.JsonUtil; import com.artfess.base.util.StringUtil; import com.artfess.base.util.UniqueIdUtil; import com.artfess.base.util.time.DateFormatUtil; import com.artfess.base.util.time.TimeUtil; import com.artfess.bpm.api.cmd.ActionCmd; import com.artfess.bpm.api.cmd.ProcessInstCmd; import com.artfess.bpm.api.constant.ActionType; import com.artfess.bpm.api.constant.BPMN20ExtConst; import com.artfess.bpm.api.constant.BpmConstants; import com.artfess.bpm.api.constant.EventType; import com.artfess.bpm.api.constant.NodeType; import com.artfess.bpm.api.constant.PrivilegeMode; import com.artfess.bpm.api.constant.TaskActionType; import com.artfess.bpm.api.constant.TaskType; import com.artfess.bpm.api.context.BpmContextUtil; import com.artfess.bpm.api.context.ContextThreadUtil; import com.artfess.bpm.api.event.BpmDefinitionDelEvent; import com.artfess.bpm.api.event.NoExecutorEvent; import com.artfess.bpm.api.event.NoExecutorModel; import com.artfess.bpm.api.inst.ISkipCondition; import com.artfess.bpm.api.model.delegate.BpmDelegateTask; import com.artfess.bpm.api.model.form.FormType; import com.artfess.bpm.api.model.identity.BpmIdentity; import com.artfess.bpm.api.model.process.def.BpmDefExtProperties; import com.artfess.bpm.api.model.process.def.BpmDefinition; import com.artfess.bpm.api.model.process.def.BpmProcessDef; import com.artfess.bpm.api.model.process.def.BpmProcessDefExt; import com.artfess.bpm.api.model.process.def.IGlobalRestfulPluginDef; import com.artfess.bpm.api.model.process.def.NodeProperties; import com.artfess.bpm.api.model.process.def.Restful; import com.artfess.bpm.api.model.process.inst.BpmProcessInstance; import com.artfess.bpm.api.model.process.nodedef.BpmNodeDef; import com.artfess.bpm.api.model.process.nodedef.ext.SignNodeDef; import com.artfess.bpm.api.model.process.nodedef.ext.SubProcessNodeDef; import com.artfess.bpm.api.model.process.nodedef.ext.UserTaskNodeDef; import com.artfess.bpm.api.model.process.nodedef.ext.extmodel.Button; import com.artfess.bpm.api.model.process.task.BpmTask; import com.artfess.bpm.api.model.process.task.SkipResult; import com.artfess.bpm.api.plugin.core.context.BpmPluginContext; import com.artfess.bpm.api.plugin.core.def.BpmExecutionPluginDef; import com.artfess.bpm.api.plugin.core.def.BpmPluginDef; import com.artfess.bpm.api.plugin.core.def.BpmTaskPluginDef; import com.artfess.bpm.api.plugin.core.def.TaskActionHandlerDef; import com.artfess.bpm.api.plugin.core.factory.BpmPluginFactory; import com.artfess.bpm.api.plugin.core.runtime.BpmExecutionPlugin; import com.artfess.bpm.api.plugin.core.runtime.BpmTaskPlugin; import com.artfess.bpm.api.plugin.core.task.TaskActionHandlerConfig; import com.artfess.bpm.api.service.BpmDefinitionAccessor; import com.artfess.bpm.api.service.BpmDefinitionService; import com.artfess.bpm.api.service.BpmFormService; import com.artfess.bpm.api.service.BpmTaskActionService; import com.artfess.bpm.api.service.RestfulService; import com.artfess.bpm.api.service.SignService; import com.artfess.bpm.defxml.entity.ExtensionElements; import com.artfess.bpm.defxml.entity.FlowElement; import com.artfess.bpm.engine.form.BpmFormFactory; import com.artfess.bpm.engine.task.cmd.DefaultTaskFinishCmd; import com.artfess.bpm.engine.task.skip.SkipConditionUtil; import com.artfess.bpm.model.form.FormModel; import com.artfess.bpm.natapi.task.NatTaskService; import com.artfess.bpm.persistence.dao.BpmExeStackRelationDao; import com.artfess.bpm.persistence.manager.BpmDefinitionManager; import com.artfess.bpm.persistence.manager.BpmProcessInstanceManager; import com.artfess.bpm.persistence.manager.BpmTaskDueTimeManager; import com.artfess.bpm.persistence.manager.BpmTaskManager; import com.artfess.bpm.persistence.model.BpmBusLink; import com.artfess.bpm.persistence.model.BpmExeStackRelation; import com.artfess.bpm.persistence.model.BpmTaskDueTime; import com.artfess.bpm.persistence.model.DefaultBpmCheckOpinion; import com.artfess.bpm.persistence.model.DefaultBpmDefinition; import com.artfess.bpm.persistence.model.DefaultBpmTask; import com.artfess.bpm.persistence.util.BpmStackRelationUtil; import com.artfess.uc.api.impl.util.ContextUtil; import com.artfess.uc.api.model.IUser; import com.artfess.uc.api.service.IUserService; /** * *
 * 描述:BPM常用解析工具类	
 * 构建组:x5-bpmx-core
 * 作者:csx
 * 邮箱:chensx@jee-soft.cn
 * 日期:2014-2-10-下午2:52:16
 * 版权:广州宏天软件有限公司版权所有
 * 
*/ public class BpmUtil { /** * 根据规则模版获取标题。 * *
	 * 示例:
	 * String rule="{depart:某个部门}申请{时间}公司{活动}";
	 * Map map=new HashMap();
	 * map.put("depart","测试部");
	 * map.put("时间","周末");
	 * map.put("活动","踏青");
	 * String subject=BpmUtil.getTitleByRule(rule,map);
	 * 返回:
	 * 测试部申请周末公司踏青
	 * 
* * @param titleRule * 主题规则 * @param map * 变量map,用于替换规则中的变量。 * @return String */ public static String getTitleByRule(String titleRule, Map map) { if (StringUtils.isEmpty(titleRule)) return ""; Pattern regex = Pattern.compile("\\{(.*?)\\}", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); Matcher matcher = regex.matcher(titleRule); while (matcher.find()) { String tag = matcher.group(0); String rule = matcher.group(1); String[] aryRule = rule.split(":"); String name = ""; if (aryRule.length == 1) { name = rule; } else { name = aryRule[1]; } if (map.containsKey(name)) { Object obj = map.get(name); if (obj != null) { try { titleRule = titleRule.replace(tag, obj.toString()); } catch (Exception e) { titleRule = titleRule.replace(tag, ""); } } else { titleRule = titleRule.replace(tag, ""); } } else { titleRule = titleRule.replace(tag, ""); } } return titleRule; } /** * 将activi的任务转换成BpmTask对象实例。 * * @param delegateTask * @return BpmTask * @throws Exception */ public static BpmTask convertTask(BpmDelegateTask delegateTask) throws Exception { String taskId = delegateTask.getId(); String instId = (String) delegateTask.getVariable(BpmConstants.PROCESS_INST_ID); String bpmnDefId = delegateTask.getBpmnDefId(); BpmDefinitionService bpmDefinitionService = AppUtil.getBean(BpmDefinitionService.class); DefaultBpmDefinition def = (DefaultBpmDefinition) bpmDefinitionService.getByBpmnDefId(bpmnDefId); ActionCmd cmd=ContextThreadUtil.getActionCmd(); BpmProcessInstance bpmProcessInstance= (BpmProcessInstance) cmd.getTransitVars(BpmConstants.PROCESS_INST); BpmFormService bpmFormService =BpmFormFactory.getFormService(FormType.MOBILE); FormModel formModel = bpmFormService.getByDefId(def.getId(), delegateTask.getTaskDefinitionKey(), bpmProcessInstance,true); int supportMobile=0; if(formModel!=null && !formModel.isFormEmpty()){ supportMobile=1; } DefaultBpmTask task = new DefaultBpmTask(); task.setId(taskId); task.setSubject(bpmProcessInstance.getSubject()); task.setTaskId(taskId); task.setDueTime(delegateTask.getDueDate()); task.setSuspendState((short) delegateTask.getSuspensionState()); task.setExecId(delegateTask.getExecutionId()); task.setName(delegateTask.getName()); task.setNodeId(delegateTask.getTaskDefinitionKey()); task.setProcInstId(instId); task.setBpmnInstId(delegateTask.getProcessInstanceId()); task.setOwnerId(BpmConstants.EmptyUser); task.setAssigneeId(BpmConstants.EmptyUser); task.setPriority((long) delegateTask.getPriority()); task.setProcDefId(def.getDefId()); task.setProcDefKey(def.getDefKey()); task.setProcDefName(def.getName()); task.setStatus(TaskType.NORMAL.name()); task.setBpmnDefId(bpmnDefId); task.setTypeId(def.getTypeId()); task.setSupportMobile(supportMobile); task.setCreateTime(delegateTask.getCreateTime()); if(ActionType.BACK.getKey().equals(cmd.getActionName())||ActionType.BACK_TO_START.getKey().equals(cmd.getActionName())){ task.setStatus(TaskType.BACK.name()); } //规则调整:更新实例标题的两个时机:1、实例创建时;2、发起人节点任务完成时 //重新设置标题 // BpmProcessInstanceManager bpmProcessInstanceManager = AppUtil.getBean(BpmProcessInstanceManager.class); // BpmDefinitionAccessor bpmDefinitionAccessor = AppUtil.getBean(BpmDefinitionAccessor.class); // DefaultBpmProcessInstance instance = bpmProcessInstanceManager.get(task.getProcInstId()); // if(BeanUtils.isNotEmpty(instance)){ // BpmProcessDef bpmDefinition = bpmDefinitionAccessor.getBpmProcessDef(instance.getProcDefId()); // // DefaultProcessInstCmd cInstCmd =new DefaultProcessInstCmd(); // cInstCmd.setFlowKey(instance.getProcDefKey()); // cInstCmd.setBusData(cmd.getBusData()); // cInstCmd.setVariables(cmd.getVariables()); // cInstCmd.putTransitVars(cmd.getTransitVars()); // cInstCmd.setInstId(instance.getId()); // cInstCmd.setBusinessKey(instance.getBizKey()); // subject = bpmProcessInstanceManager.getSubject(bpmDefinition, cInstCmd, instance); // task.setSubject(subject); // instance.setSubject(subject); // bpmProcessInstanceManager.update(instance); // } return task; } /** * 根据流程任务对象复制新的任务。 * *
	 * 1.新的任务的ExecId为空,表示派生的任务。
	 * 2.设定父任务。
	 * 3.设定任务类型。
	 * 4.设定执行人。
	 * 
* * @param task * @param parentTaskId * @param taskType * @param user * @return DefaultBpmTask */ public static DefaultBpmTask convertTask(DefaultBpmTask task, String parentTaskId, TaskType taskType, IUser user) { DefaultBpmTask cloneTask = (DefaultBpmTask) task.clone(); cloneTask.setId(UniqueIdUtil.getSuid()); cloneTask.setParentId(parentTaskId); cloneTask.setExecId(""); cloneTask.setTaskId(""); cloneTask.setStatus(taskType.name()); cloneTask.setAssigneeId(user.getUserId()); cloneTask.setOwnerId(user.getUserId()); cloneTask.setCreateTime(LocalDateTime.now()); return cloneTask; } /** * 根据流程定义ID获取流程的扩展属性。 * * @param bpmnDefId * @return BpmDefExtProperties * @throws Exception */ public static BpmDefExtProperties getExtProperties(String bpmnDefId) throws Exception { BpmDefinitionService bpmDefinitionService = AppUtil.getBean(BpmDefinitionService.class); BpmProcessDef procDef = bpmDefinitionService.getBpmProcessDef(bpmnDefId); BpmProcessDefExt procExt = procDef.getProcessDefExt(); BpmDefExtProperties extProperties = procExt.getExtProperties(); return extProperties; } @SuppressWarnings("unchecked") private static Object[] getDefProperties(BpmProcessInstance instance, String nodeId) throws Exception { Object[] aryObj = new Object[3]; String defId = instance.getProcDefId(); BpmDefinitionAccessor bpmDefinitionAccessor = (BpmDefinitionAccessor) AppUtil.getBean("bpmDefinitionAccessor"); BpmDefinitionManager bpmDefinitionManager = AppUtil.getBean(BpmDefinitionManager.class); BpmDefinition bpmDefinition = bpmDefinitionManager.getById(defId); BpmNodeDef nodeDef = null; BpmProcessDef processDef = null; UserTaskNodeDef taskNodeDef = null; NodeProperties properties = null; String parentId = instance.getParentInstId(); if (StringUtil.isNotZeroEmpty(parentId)) { BpmProcessInstanceManager instanceManager = AppUtil.getBean(BpmProcessInstanceManager.class); BpmProcessInstance parentInstance = instanceManager.get(parentId); nodeDef = bpmDefinitionAccessor.getBpmNodeDef(parentInstance.getProcDefId(), nodeId); if(BeanUtils.isNotEmpty(nodeDef)){ taskNodeDef = (UserTaskNodeDef) nodeDef; properties = taskNodeDef.getLocalProperties(); processDef = nodeDef.getRootProcessDef(); } } if(BeanUtils.isEmpty(nodeDef)){ nodeDef = bpmDefinitionAccessor.getBpmNodeDef(defId, nodeId); taskNodeDef = (UserTaskNodeDef) nodeDef; properties = taskNodeDef.getLocalProperties(); processDef = nodeDef.getRootProcessDef(); } aryObj[0] = properties; aryObj[1] = processDef; aryObj[2] = bpmDefinition; return aryObj; } /** * 是否允许节点执行人为空。 * * @param bpmnDefId * @param nodeId * @return boolean * @throws Exception */ @SuppressWarnings("rawtypes") public static boolean isAllowEmptyIdentity(BpmProcessInstance instance, String nodeId) throws Exception { boolean isAllowEmpty = false; Object[] aryObj = getDefProperties(instance, nodeId); NodeProperties properties = (NodeProperties) aryObj[0]; BpmProcessDef procDef = (BpmProcessDef) aryObj[1]; if (properties != null) { isAllowEmpty = properties.isAllowExecutorEmpty(); } if (!isAllowEmpty) { BpmProcessDefExt procExt = procDef.getProcessDefExt(); BpmDefExtProperties extProperties = procExt.getExtProperties(); isAllowEmpty = extProperties.isAllowExecutorEmpty(); } return isAllowEmpty; } /** * 获取跳过第一个节点。 * * @param defId * @return boolean * @throws Exception */ public static boolean getSkipFirstNode(String defId) throws Exception { BpmDefinitionAccessor bpmDefinitionAccessor = (BpmDefinitionAccessor) AppUtil.getBean("bpmDefinitionAccessor"); BpmProcessDef procDef = bpmDefinitionAccessor.getBpmProcessDef(defId); BpmProcessDefExt procExt = procDef.getProcessDefExt(); BpmDefExtProperties extProperties = procExt.getExtProperties(); return extProperties.isSkipFirstNode(); } /** * 根据bpmnDefId获取流程定义。 * * @param bpmnDefId * @return BpmProcessDef<BpmProcessDefExt> * @throws Exception */ public static BpmProcessDef getProcessDef(String bpmnDefId) throws Exception { BpmDefinitionService bpmDefinitionService = AppUtil.getBean(BpmDefinitionService.class); BpmProcessDef procDef = bpmDefinitionService.getBpmProcessDef(bpmnDefId); return procDef; } /** * 根据流程DEFID获取流程定义。 * * @param defId * @return BpmProcessDef<BpmProcessDefExt> * @throws Exception */ public static BpmProcessDef getProcessDefByDefId(String defId) throws Exception { BpmDefinitionAccessor bpmDefinitionAccessor = (BpmDefinitionAccessor) AppUtil.getBean("bpmDefinitionAccessor"); BpmProcessDef procDef = bpmDefinitionAccessor.getBpmProcessDef(defId); return procDef; } /** * * 是否允许转办,如果是内部子流程,则会取父流程的参数 * * @param bpmNodeDef * @return */ public static boolean IsAllowTransTo(BpmNodeDef bpmNodeDef) { boolean isAllowTransTo = true; if (bpmNodeDef.getBpmProcessDef().getProcessDefExt() == null) {// 子流程 bpmNodeDef = bpmNodeDef.getParentBpmNodeDef(); } try { isAllowTransTo = bpmNodeDef.getBpmProcessDef().getProcessDefExt().getExtProperties().isAllowTransTo(); } catch (Exception e) {} return isAllowTransTo; } /** * * 是否使用表单主版本,如果不是则取全局设置,如果全局未设置则取流程启动时的版本 * * @param bpmNodeDef * @return */ public static String getUseMainForm(BpmNodeDef bpmNodeDef) { String useMainForm = ""; if (bpmNodeDef.getBpmProcessDef().getProcessDefExt() == null) {// 子流程 bpmNodeDef = bpmNodeDef.getParentBpmNodeDef(); } try { useMainForm = bpmNodeDef.getBpmProcessDef().getProcessDefExt().getExtProperties().getUseMainForm(); } catch (Exception e) {} return useMainForm; } /** * 默认完成任务,在默认跳过时使用。 * * @param taskId * void * @throws Exception */ public static void finishTask(BpmTask bpmTask) throws Exception { String taskId = bpmTask.getId(); // 跳过结果。 SkipResult result = bpmTask.getSkipResult(); ActionCmd actionCmd = ContextThreadUtil.getActionCmd(); // 目标节点 String destination = actionCmd.getDestination(); // 节点人员 Map> identityMap = actionCmd.getBpmIdentities(); BpmTaskActionService bpmTaskActionService = AppUtil.getBean(BpmTaskActionService.class); Map boMap = BpmContextUtil.getBoFromContext(); DefaultTaskFinishCmd cmd = new DefaultTaskFinishCmd(); //BeanUtils.copyProperties(cmd, actionCmd); cmd.addTransitVars(BpmConstants.BO_INST, boMap); if (!result.isSkipTask()) { cmd.setDestination(destination); } else { cmd.setDestination(""); } cmd.setTaskId(taskId); cmd.setBpmIdentities(identityMap); cmd.setBusData(actionCmd.getBusData()); cmd.setDataMode(actionCmd.getDataMode()); cmd.setActionName(TaskActionType.AGREE.getKey()); String skipType = result.getSkipType(); cmd.addTransitVars(BpmConstants.BPM_SKIP_TYPE, skipType); cmd.addTransitVars(BpmConstants.BPM_TASK, bpmTask); bpmTaskActionService.finishTask(cmd); } /** * 获取通知类型。 * *
	 * 	1.如果流程状态为测试,那么就获取流程定义测试状态的通知类型。
	 *  2.先获取节点的通知类型。
	 *  3.获取流程定义的通知类型。
	 * 
* * @param bpmnDefId * @param nodeId * @return String * @throws Exception */ @SuppressWarnings("rawtypes") public static String getNotifyType(BpmProcessInstance instance, String nodeId) throws Exception { Object[] aryObj = getDefProperties(instance, nodeId); NodeProperties properties = (NodeProperties) aryObj[0]; BpmProcessDef procDef = (BpmProcessDef) aryObj[1]; //BpmDefinition bpmDefinition = (BpmDefinition) aryObj[2]; BpmProcessDefExt ext = procDef.getProcessDefExt(); BpmDefExtProperties prop = ext.getExtProperties(); /*if (BpmDefinition.TEST_STATUS.TEST.equals(bpmDefinition.getTestStatus())) { return prop.getTestNotifyType(); }*/ String notifyType = ""; if (properties != null) { notifyType = properties.getNotifyType(); } if (StringUtil.isNotEmpty(notifyType)) return notifyType; notifyType = prop.getNotifyType(); return notifyType; } /** * * @param task * @return * @throws Exception */ public static String getNotifyType(BpmTask task) throws Exception { if (BeanUtils.isEmpty(task)) { return ""; } BpmProcessInstanceManager instanceManager = AppUtil.getBean(BpmProcessInstanceManager.class); return getNotifyType(instanceManager.get(task.getProcInstId()), task.getNodeId()); } /** * 当没有执行人时发布事件。 * * @param model * void */ public static void publishNoExecutorEvent(NoExecutorModel model) { NoExecutorEvent ev = new NoExecutorEvent(model); //AppUtil.getBean(NoExecutorEventListener.class); AppUtil.publishEvent(ev); } /** * 设置任务是否跳过。 * * @param bpmTask * void * @throws Exception */ public static void setTaskSkip(BpmTask bpmTask) throws Exception { if (bpmTask.getSkipResult().isHasGetSkip()) return; SkipResult skipResult = new SkipResult(); skipResult.setHasGetSkip(true); bpmTask.setSkipResult(skipResult); ActionCmd cmd = ContextThreadUtil.getActionCmd(); BpmProcessDef procDef = BpmUtil.getProcessDefByDefId(bpmTask.getProcDefId()); BpmDefExtProperties extProperties = procDef.getProcessDefExt().getExtProperties(); // 发起流程判断 if (cmd instanceof ProcessInstCmd) { // 跳过第一个节点。 boolean skipFirstNode = extProperties.isSkipFirstNode(); if (skipFirstNode) { skipResult.setSkipTask(true); skipResult.setSkipType(SkipResult.SKIP_FIRST); } } //任务审批判断。 //只要跳转规则满足要求,那么就允许任务直接跳过。 else{ String skipRules= extProperties.getSkipRules(); //当跳转规则为空时,查找当前任务属性设置是否为“执行人为空跳过”,如果是,则将跳转规则设置为“SKIP_EMPTY_USER” if(StringUtil.isEmpty(skipRules)){ try { BpmProcessInstance instance = (BpmProcessInstance) cmd.getTransitVars(BpmConstants.PROCESS_INST); Object[] aryObj = getDefProperties(instance, bpmTask.getNodeId()); NodeProperties properties = (NodeProperties) aryObj[0]; if(properties.isSkipExecutorEmpty()){ skipRules = SkipResult.SKIP_EMPTY_USER; } } catch (Exception e) {} } if(StringUtil.isEmpty(skipRules)) return; String[] aryRules=skipRules.split(","); for(String rule:aryRules){ ISkipCondition condition= SkipConditionUtil.getSkipConditionByType(rule); boolean rtn=condition.canSkip(bpmTask); if(!rtn ) continue; skipResult.setSkipTask(true); skipResult.setSkipType(condition.getType()); break; } } } /** * 根据用户名和ID获取用户对象。 * * @param userId * @param userName * @return User */ public static IUser getUser(String userId, String userName) { IUser user = new IUser() { /** * serialVersionUID * * @since 1.0.0 */ private static final long serialVersionUID = -3279144470311301256L; String userId = ""; String fullName = ""; public String getIdentityType() { return null; } public void setUserId(String userId) { this.userId = userId; } public void setFullname(String fullName) { this.fullName = fullName; } public void setAccount(String account) { } public String getUserId() { return this.userId; } public String getPassword() { return null; } public String getMobile() { return null; } public String getFullname() { return this.fullName; } public String getEmail() { return null; } public String getAccount() { return null; } public void setAttributes(Map map) { } public Map getAttributes() { return null; } public boolean isAdmin() { return false; } @Override public String getAttrbuite(String key) { return ""; } @Override public String getPhoto() { return null; } @Override public String getWeixin() { return null; } @Override public Integer getHasSyncToWx() { return null; } @Override public boolean isEnable() { return true; } @Override public Collection getAuthorities() { return null; } @Override public String getUsername() { return null; } @Override public boolean isAccountNonExpired() { return false; } @Override public boolean isAccountNonLocked() { return false; } @Override public boolean isCredentialsNonExpired() { return false; } @Override public boolean isEnabled() { return false; } @Override public Integer getStatus() { return null; } @Override public String getTenantId() { // TODO Auto-generated method stub return null; } @Override public LocalDateTime getPwdCreateTime() { // TODO Auto-generated method stub return null; } @Override public String getClientId() { // TODO Auto-generated method stub return null; } @Override public String getClientToken() { // TODO Auto-generated method stub return null; } @Override public LocalDate getEntryDate() { return null; } @Override public LocalDateTime getLockedTime() { return null; } @Override public Integer getLockedStatus() { return null; } @Override public Integer getUserType() { return null; } @Override public LocalDateTime getLastLoginTime() { return null; } @Override public String getSkin() { return "light"; } }; user.setUserId(userId); user.setFullname(userName); return user; } /** * 根据用户ID返回用户对象。 * * @param userId * @return User */ public static IUser getUser(String userId) { IUserService userService = AppUtil.getBean(IUserService.class); IUser user = userService.getUserById(userId); return user; } /** * 根据流程实例数据构建业务表中间数据。 * * @param instance * @return BpmBusLink */ public static BpmBusLink buildBusLink(BpmProcessInstance instance, ObjectNode result, String saveMode) { //获取顶级的流程实例。 BpmProcessInstanceManager instanceManager = AppUtil.getBean(BpmProcessInstanceManager.class); instance = instanceManager.getTopBpmProcessInstance(instance); BpmBusLink busLink = buildBusLink(instance); busLink.setSaveMode(saveMode); busLink.setIsMain("0".equals(result.get("parentId").asText()) ? 1 : 0); // 设置实体数据名称。 if(result.get("boAlias")!=null) { busLink.setBoDefCode(result.get("boAlias").asText()); } busLink.setFormIdentify(result.get("boEnt").get("name").asText()); ObjectNode boEnt=(ObjectNode) result.get("boEnt"); boolean isNumber=BeanUtils.isNotEmpty(boEnt.get("pkType"))&&"number".equals(boEnt.get("pkType").asText()); if (isNumber) { busLink.setBusinesskey(new Long(result.get("pk").asLong())); } else { busLink.setBusinesskeyStr(result.get("pk").asText()); } if(StringUtil.isNotEmpty(instance.getSysCode())){ busLink.setSysCode(instance.getSysCode()); } return busLink; } /** * 根据流程实例数据构建业务表中间数据。 * * @param instance * @return */ public static BpmBusLink buildBusLink(BpmProcessInstance instance) { BpmBusLink busLink = new BpmBusLink(); busLink.setId(UniqueIdUtil.getSuid()); busLink.setDefId(instance.getProcDefId()); busLink.setProcInstId(instance.getId()); IUser curUser = ContextUtil.getCurrentUser(); busLink.setStartId(curUser.getUserId()); busLink.setStartor(curUser.getFullname()); busLink.setCreateDate(LocalDateTime.now()); if(StringUtil.isNotEmpty(instance.getSysCode())){ busLink.setSysCode(instance.getSysCode()); } return busLink; } /** * 根据bpmn20流程定义xml文件,流程属性 * * @param flowElement * @param qname * @return */ public static List getFlowElementExtension(FlowElement flowElement, QName qname) { List extensions = new ArrayList(); ExtensionElements extensionElements = flowElement.getExtensionElements(); if (extensionElements == null) return extensions; List objects = extensionElements.getAny(); for (Object obj : objects) { if (obj instanceof Element) { Element el = (Element) obj;// 要相同的命名空间 QName qn = new QName(el.getNamespaceURI(), el.getLocalName()); if (qname.equals(qn)) { extensions.add(el.getNodeValue()); } } } return extensions; } public static Integer getFlowElementOrder(FlowElement flowElement) { Integer nodeOrder = 0; List extensions = getFlowElementExtension(flowElement, BPMN20ExtConst._ORDER_QNAME); if (BeanUtils.isNotEmpty(extensions)) { String s = (String) extensions.get(0); if(StringUtil.isNotEmpty(s) && !"null".equals(s)){ nodeOrder = Integer.parseInt(s); } } return nodeOrder; } /** * 获取按钮,并按照当前节点和任务状态过滤按钮 * * @param bpmNodeDef * 流程节点 * @param task * 任务 * @param dataObjects * 数据对象 * @return * @throws Exception */ public static List