package com.vci.web.service.impl; import com.vci.bo.FlowNoticeInfo; import com.vci.constant.WFVariablesKeyConstant; import com.vci.corba.common.PLException; import com.vci.corba.common.data.UserEntityInfo; import com.vci.corba.omd.data.BusinessObject; import com.vci.corba.omd.data.LinkObject; import com.vci.corba.workflow.data.FlowInstanceInfo; import com.vci.corba.workflow.data.MapTransfersInfo; import com.vci.corba.wf.data.TasksAssignedInfo; import com.vci.dto.ProcessStartConfigDTO; import com.vci.dto.ProcessTemplateVO; import com.vci.dto.VciFileObjectDTO; import com.vci.omd.utils.ObjectTool; import com.vci.pagemodel.ProcessNodeVO; import com.vci.pagemodel.ProcessOutcomeVO; import com.vci.pagemodel.ProcessTaskVO; import com.vci.pagemodel.ProcessUserVO; import com.vci.starter.web.annotation.FlowNotifyAfter; import com.vci.starter.web.annotation.FlowNotifyBefore; import com.vci.starter.web.annotation.FlowNotifyWeb; import com.vci.starter.web.constant.QueryOptionConstant; import com.vci.starter.web.enumpck.DataSecretEnum; import com.vci.starter.web.exception.VciBaseException; import com.vci.starter.web.pagemodel.DataGrid; import com.vci.starter.web.pagemodel.SessionInfo; import com.vci.starter.web.util.BusAnnotationUtil; import com.vci.starter.web.util.LangBaseUtil; import com.vci.starter.web.util.VciDateUtil; import com.vci.web.dao.WebProcessDaoI; import com.vci.web.service.*; import com.vci.web.util.PlatformClientUtil; import com.vci.web.util.WebUtil; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import java.util.*; import java.util.Map.Entry; /** * 流程执行服务 * * @author weidy */ @Service public class WebProcessCommandServiceImpl implements WebProcessCommandServiceI { private Logger logger = LoggerFactory.getLogger(getClass()); private final String reject = "不同意"; @Autowired private WebProcessDefineServiceI processDefineService; @Autowired private WebLoServiceI loService; @Autowired private WebBoServiceI boService; @Autowired private WebProcessDaoI processDao; @Autowired private WebLifeCycleServiceI lifeCycleService; /** * 文件上传服务 */ @Autowired private VciFileUploadServiceI fileService; /** * 多语言的前缀 */ private final String msgCodePrefix = "com.vci.web.flow."; /** * 平台的客户端 */ @Autowired private PlatformClientUtil platformClientUtil; @Override public boolean deploy(String name, String type, String key, String xmlContext) throws VciBaseException { // TODO Auto-generated method stub return false; } /** * 启动流程 * @param config 启动流程相关配置 * @param processNodeUsers 各个节点的负责人信息 * @param variablesInfo 相关变量 * @throws VciBaseException */ @Override public void startProcess(ProcessStartConfigDTO config, Map> processNodeUsers, Map variablesInfo) throws VciBaseException { //1. 校验流程是否存在 //2. 整理业务数据 //3. 整理每个节点的用户 //4. 整理变量,包括将显示表格的方式添加到变量的方法 //5. 发起流程 WebUtil.alertNotNull(config, "发起流程配置信息"); WebUtil.alertNotNull(config.getDeployId(), "流程部署主键", config.getBtmType(), "数据所属业务类型", config.getOids(), "数据所属主键", config.getTitle(), "流程名称"); if (config.getTitle().length() > 127) { config.setTitle(config.getTitle().substring(0, 127)); } //weidy修改获取当前用户的方法 SessionInfo si = WebUtil.getCurrentUserSessionInfo(); //校验流程的信息,和设置每个任务的人员信息 ProcessTemplateVO template = processDao.getTemplateByDeployId(config.getDeployId().trim()); List allNodes = processDao.getAllProcessNode(template.getOid()); String firstNodeName = processDao.getFirstNodeName(config.getDeployId().trim()); WebUtil.alertNotNull(firstNodeName, "没有获取流程的第一个任务节点"); String[] firstNodeUserNames = null; if (processNodeUsers == null || !processNodeUsers.containsKey(firstNodeName)) { firstNodeUserNames = new String[]{"user:" + si.getUserId()}; } else { List firstNodeUsers = processNodeUsers.get(firstNodeName); firstNodeUserNames = getProcessUserInfo(firstNodeUsers); } //全部的任务 String[] allTaskName = new String[allNodes.size()]; //任务的处理人 String[][] allTaskNameUsers = new String[allNodes.size()][]; for (int i = 0; i < allNodes.size(); i++) { ProcessNodeVO node = allNodes.get(i); if (node.getName().equals(firstNodeName)) { allTaskNameUsers[i] = firstNodeUserNames; } else { String[] thisTaskUser = new String[]{""}; if (processNodeUsers != null && processNodeUsers.containsKey(node.getName())) { String[] userInfos = getProcessUserInfo(processNodeUsers.get(node.getName())); if (userInfos != null && userInfos.length > 0) { thisTaskUser = userInfos; } } allTaskNameUsers[i] = thisTaskUser; } allTaskName[i] = node.getName(); } Map conditionMap = WebUtil.getOidQuery(config.getOids()); conditionMap.put(WebBoServiceI.QUERY_FILTER_SECRET, "false"); conditionMap.put(WebBoServiceI.QUERY_FILTER_DATARIGHT, "false"); List allCbo = boService.queryCBO(config.getBtmType().toLowerCase().trim(), conditionMap); if (allCbo == null || allCbo.size() == 0) { throw new VciBaseException(msgCodePrefix + "dataNotNull", new String[]{}); } //查询数据是否已经发起了流程 //查询input连接里是不是有流程实例,并且流程实例不等于终止 conditionMap.put("oid", " in (select f_oid from plt_" + processDao.getTaskDataLink() + " where oid " + conditionMap.get("oid").replace("\\IN", " in ") + ")"); List workInstanceCbos = boService.queryCBO(processDao.getWorkIntanceBtmType(), conditionMap); if (workInstanceCbos != null && workInstanceCbos.size() > 0) { for (BusinessObject workInstance : workInstanceCbos) { if (!workInstance.lcStatus.equalsIgnoreCase("Obsoleted")) { throw new VciBaseException(msgCodePrefix + "dataSubmitedToProcess", new String[]{workInstance.name, workInstance.creator}); } } } String[] objectPropertyKeys = new String[]{"Oid", "RevisionOid", "NameOid", "BTMName"};//业务数据的信息 String[][] objectPropertyValues = new String[allCbo.size()][4]; String[] objIds = new String[allCbo.size()];//业务数据的组件 for (int i = 0; i < allCbo.size(); i++) { BusinessObject cbo = allCbo.get(i); String[] values = new String[4]; values[0] = cbo.oid; values[1] = cbo.revoid; values[2] = cbo.nameoid; values[3] = cbo.btName; objectPropertyValues[i] = values; objIds[i] = cbo.oid; } FlowInstanceInfo flowInstanceInfo = new FlowInstanceInfo(); flowInstanceInfo.creator = si.getUserId(); flowInstanceInfo.templatePuid = template.getOid(); flowInstanceInfo.tableName = config.getBtmType().toLowerCase().trim(); flowInstanceInfo.applicant = si.getUserId(); flowInstanceInfo.desc = config.getDescription() == null ? "" : config.getDescription(); flowInstanceInfo.processType = config.getBtmType().toLowerCase().trim(); flowInstanceInfo.templateName = template.getName(); flowInstanceInfo.clsfOid = ""; flowInstanceInfo.partList = ""; flowInstanceInfo.processName = config.getTitle(); MapTransfersInfo[] allVariables = swapVariable(config, variablesInfo); long currentTime =0L; try{ currentTime = platformClientUtil.getFrameworkService().getSystemTime(); }catch (Throwable e){ throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[0],e); } FlowNoticeInfo noticeInfo = new FlowNoticeInfo(); noticeInfo.setServerTime(currentTime); noticeInfo.setStartConfigDTO(config); noticeInfo.setVariablesInfo(variablesInfo); noticeInfo.setProcessTemplateVO(template); BusAnnotationUtil.callForAnnotation(FlowNotifyWeb.class, FlowNotifyBefore.class,noticeInfo); String processInstanceId = ""; /*try { if (config.isAutoSubmitFirst()) { processInstanceId = processDao.getWorkService().startProcessAndExecuteFirstNode(template.getOid(), flowInstanceInfo, objIds, getUserEntityInfo(), firstNodeUserNames, "", allTaskName, allTaskNameUsers, allVariables, objectPropertyKeys, objectPropertyValues); }else{ processInstanceId = processDao.getWorkService().startPocessByPLMv1( *//** * String processDefinitionKey, 流程模板主键 * FlowInstanceInfo flowInstanceInfo, 流程实例 * String[] objId, 数据对象id * UserEntityInfo userEntityInfo, 用户Info * String[] userName, 用户名 * String outcome, 指向 * String[] tasknames, 业务名称 * String[][] taskUserNames, 所属用户名 * MapTransfersInfo[] mapTransfersInfos, 移交Info * String[] objectProperty, 业务属性 * String[][] objectPropertyValues 业务属性值 *//* template.getOid(), flowInstanceInfo, objIds, getUserEntityInfo(), firstNodeUserNames, "", allTaskName, allTaskNameUsers, allVariables, objectPropertyKeys, objectPropertyValues ); } } catch (PLException e) { throw WebUtil.getVciBaseException(e); }*/ if (StringUtils.isNotBlank(config.getStartStatus())) { try { lifeCycleService.transCboStatus(allCbo, config.getStartStatus()); } catch (Exception e) { throw new VciBaseException("启动流程时,批量跃迁生命周期状态失败!", new Object[]{}, e); } } callAfter(processInstanceId,null,null,currentTime); } /** * 执行流程之前调用 * @param preWorkitemList 任务的信息 */ private void callBefore(List preWorkitemList,String outcome,String note,long currentTime){ if(currentTime == 0L) { try { currentTime = platformClientUtil.getFrameworkService().getSystemTime(); } catch (Throwable e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[0], e); } } FlowNoticeInfo noticeInfo = new FlowNoticeInfo(); noticeInfo.setFinishItemList(preWorkitemList); noticeInfo.setServerTime(currentTime); noticeInfo.setOutcome(outcome); noticeInfo.setNote(note); if(!CollectionUtils.isEmpty(preWorkitemList)){ //如果不允许执行后续,请直接抛出异常 BusAnnotationUtil.callForAnnotation(FlowNotifyWeb.class, FlowNotifyBefore.class,noticeInfo); } } /** * 执行流程之后 * @param processInstanceId 流程的主键 * @param finishWorkItemList 完成的任务的信息 * @param mill 服务器时间 */ private void callAfter(String processInstanceId,List newWorkItemList,List finishWorkItemList,long mill){ if(newWorkItemList == null){ newWorkItemList = new ArrayList<>(); } if(StringUtils.isNotBlank(processInstanceId)){ //说明是发起流程 //获取现在所有的任务信息 DataGrid undoTaskGrid = processDao.getUndoTaskByInstanceId(processInstanceId,mill); if(!CollectionUtils.isEmpty(undoTaskGrid.getData())){ newWorkItemList.addAll((List)undoTaskGrid.getData()); } } FlowNoticeInfo noticeInfo = new FlowNoticeInfo(); noticeInfo.setNewItemList(newWorkItemList); noticeInfo.setFinishItemList(finishWorkItemList); noticeInfo.setServerTime(mill); BusAnnotationUtil.callForAnnotation(FlowNotifyWeb.class, FlowNotifyAfter.class,noticeInfo); } /** * 转换变量 * * @param config 启动的配置 * @param varMap 变量的map * @return 封装好的变量对象 */ private MapTransfersInfo[] swapVariable(ProcessStartConfigDTO config, Map varMap) { List mapTransfersInfos = new ArrayList(); mapTransfersInfos.add(new MapTransfersInfo(WFVariablesKeyConstant.BTMTYPE_OLD, config.getBtmType())); mapTransfersInfos.add(new MapTransfersInfo(WFVariablesKeyConstant.OIDS_OLD, config.getOids())); if (StringUtils.isNotEmpty(config.getTableDefineCode())) { mapTransfersInfos.add(new MapTransfersInfo(WFVariablesKeyConstant.UI_TABLE_CODE, config.getTableDefineCode())); } if (StringUtils.isNotEmpty(config.getDetailInfoUrl())) { mapTransfersInfos.add(new MapTransfersInfo(WFVariablesKeyConstant.UI_DETAIL_URL, config.getDetailInfoUrl())); } if (StringUtils.isNotBlank(config.getContent())) { mapTransfersInfos.add(new MapTransfersInfo(WFVariablesKeyConstant.UI_CONTENT_CODE, config.getContent())); } mapTransfersInfos.add(new MapTransfersInfo(WFVariablesKeyConstant.DATA_MAX_SECRET, String.valueOf(config.getMaxSecret()))); if (StringUtils.isNotBlank(config.getResetStatus())) { mapTransfersInfos.add(new MapTransfersInfo(WFVariablesKeyConstant.RESET_STATUS, config.getResetStatus())); } if (StringUtils.isNotBlank(config.getStartStatus())) { mapTransfersInfos.add(new MapTransfersInfo(WFVariablesKeyConstant.START_STATUS, config.getStartStatus())); } if (StringUtils.isNotBlank(config.getReleaseStatus())) { mapTransfersInfos.add(new MapTransfersInfo(WFVariablesKeyConstant.RELEASE_STATUS, config.getReleaseStatus())); } if (StringUtils.isNotBlank(config.getUiType())) { mapTransfersInfos.add(new MapTransfersInfo(WFVariablesKeyConstant.UI_TYPE, config.getUiType())); } if (varMap != null && !varMap.isEmpty()) { for (String key : varMap.keySet()) { Object value = varMap.get(key); String strValue = ""; if (value instanceof Date) { strValue = VciDateUtil.date2Str((Date) value, VciDateUtil.DateTimeMillFormat); } else if (value instanceof Long || value instanceof Integer || value instanceof Double) { strValue = String.valueOf(value); } else { strValue = value.toString(); } mapTransfersInfos.add(new MapTransfersInfo(key, strValue)); } } return mapTransfersInfos.toArray(new MapTransfersInfo[0]); } /** * 转化为平台可以识别的用户信息 * * @param users 负责人 * @return */ private String[] getProcessUserInfo(List users) { String[] ss = new String[0]; if (users != null && users.size() > 0) { ss = new String[users.size()]; for (int i = 0; i < users.size(); i++) { ProcessUserVO user = users.get(i); if ("user".equals(user.getType())) { ss[i] = "user:" + user.getId(); } else if ("role".equals(user.getType())) { ss[i] = "role:" + user.getOid(); } else if ("dept".equals(user.getType())) { ss[i] = "dept:" + user.getOid(); } } } return ss; } /** * 批量执行任务,但是前提条件是这些任务都拥有相同的outCome */ @Override public void completeTasks(String taskIds, String outCome, String note, List nextTaskUser) throws VciBaseException { logger.info("执行流程:" + taskIds); //首先判断空值 WebUtil.alertNotNull(outCome, "执行操作", taskIds, "执行流程"); if (reject.equalsIgnoreCase(outCome) && StringUtils.isEmpty(note)) { //不同意的时候,审批意见不能为空 throw new VciBaseException("当执行操作为" + reject + "时,必须要有审批意见"); } if (note == null) { note = ""; } List allTask = processDefineService.getTaskByOid(taskIds); String[] jbpmTaskIds = null; String nextTaskName = ""; if (allTask == null) { throw new VciBaseException("没有找到流程任务", new String[]{}); } else { //说明是批量在执行,这个时候我们需要判断这些任务是否使用相同的流程模板,且当前任务的名称都相同.而且下一步任务都设置了负责人 String deployId = ""; String taskName = ""; jbpmTaskIds = new String[allTask.size()]; for (int i = 0; i < allTask.size(); i++) { ProcessTaskVO task = allTask.get(i); jbpmTaskIds[i] = task.getTaskOid(); boolean isMuti = false; if (allTask != null && allTask.size() > 1) { isMuti = true; } if (isMuti) { //平台不支持批量获取部署主键,所以只能一个任务一个任务地获取 String thisDeployId = processDefineService.getDeployIdByExecutionId(task.getExecutionId()); String thisTaskName = task.getName(); if (thisTaskName.indexOf("-") > -1) { thisTaskName = thisTaskName.substring(thisTaskName.lastIndexOf("-") + 1); } if (StringUtils.isEmpty(thisDeployId)) { deployId = thisDeployId; taskName = thisTaskName; } else { if (!thisDeployId.equals(deployId) || !thisTaskName.equals(taskName)) { throw new VciBaseException("批量执行流程时,要求使用的同一个流程模板中同一个任务节点,{0},{1}", new String[]{thisDeployId + ":" + deployId, thisTaskName + ":" + taskName}); } } } List allOutcome = processDefineService.getOutCome(task.getOid(), true); if (allOutcome != null && allOutcome.size() > 0) { boolean isFinedOc = false; for (ProcessOutcomeVO oc : allOutcome) { if (oc.getName().equals(outCome)) { if (oc.isHasSubTask()) { nextTaskName = oc.getNextTaskNames()[0]; for (Entry> allUser : oc.getProcessUsers().entrySet()) { if (allUser.getValue() == null || allUser.getValue().size() == 0) { if (isMuti) { throw new VciBaseException("批量执行流程时,要求每个任务的下一步骤任务都已经设置了负责人,{0},{1}", new String[]{outCome, allUser.getKey()}); } else if (!isMuti && (nextTaskUser == null || nextTaskUser.size() == 0)) { throw new VciBaseException("下一步骤任务{0}没有设置负责人,请先设置负责人", new String[]{allUser.getKey()}); } } } } else { nextTaskName = oc.getNextTaskName(); if (!"结束".equals(oc.getNextTaskName()) && (oc.getProcessUserVO() == null || oc.getProcessUserVO().size() == 0)) { if (isMuti) { throw new VciBaseException("批量执行流程时,要求每个任务的下一步骤任务都已经设置了负责人,{0},{1}", new String[]{outCome, oc.getName()}); } else if (!isMuti && (nextTaskUser == null || nextTaskUser.size() == 0)) { throw new VciBaseException("下一步骤任务{0}没有设置负责人,请先设置负责人", new String[]{oc.getNextTaskName()}); } } } isFinedOc = true; break; } } if (!isFinedOc) { throw new VciBaseException("任务" + task.getName() + "没有路由" + outCome, new String[]{}); } } } } //校验完成了 String[] nextTaskUsers = getProcessUserInfo(nextTaskUser); String[] objectPropertyKeys = new String[]{"Oid", "RevisionOid", "NameOid", "BTMName"}; Map conditionMap = new HashMap(); conditionMap.put("f_btwname", processDao.getWorkitemBtmType()); conditionMap.put("f_oid", QueryOptionConstant.IN + "(" + WebUtil.toInSql(taskIds) + ")"); List allLinkData = loService.queryCLO(processDao.getTaskDataLink(), conditionMap); String[][] objectPropertyValues = new String[allLinkData.size()][4]; for (int i = 0; i < allLinkData.size(); i++) { LinkObject clo = allLinkData.get(i); String[] values = new String[4]; values[0] = clo.toOid; values[1] = clo.toRevOid; values[2] = clo.toNameOid; values[3] = clo.toBTName; objectPropertyValues[i] = values; } if ("未命名路由".equalsIgnoreCase(outCome)) { outCome = ""; } List workitemList = processDao.getTaskCBOByOid(taskIds); long currentTime = 0L; try { currentTime = platformClientUtil.getFrameworkService().getSystemTime(); } catch (Throwable e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[0], e); } callBefore(workitemList,outCome,note,currentTime); /*try { if (jbpmTaskIds.length == 1) { processDao.getWorkService().completeTaskByPlatformv1(jbpmTaskIds[0], outCome, nextTaskName, note, getUserEntityInfo(), nextTaskUsers, objectPropertyKeys, objectPropertyValues); } else { processDao.getWorkService().completeTasksByPlatformv1(jbpmTaskIds, outCome, nextTaskName, note, getUserEntityInfo(), nextTaskUsers, objectPropertyKeys, objectPropertyValues); } } catch (PLException e) { throw WebUtil.getVciBaseException(e); }*/ callAfter((String)workitemList.get(0).get("executionid"),null,workitemList,currentTime); } private UserEntityInfo getUserEntityInfo() { return WebUtil.getUserEntityInfo("流程"); } /** * 转移负责人 * * @param taskOids 任务主键 * @param userIds 新的用户,只能是一个用户 * @throws VciBaseException */ @Override public void setPrincipal(String taskOids, String userIds) throws VciBaseException { WebUtil.alertNotNull(taskOids, "流程任务的主键", userIds, "用户名"); if (userIds.contains(",")) { throw new VciBaseException(msgCodePrefix + "onlyTransOneUser"); } String[] taskOidArray = taskOids.split(","); for (String taskOid : taskOidArray) { if (StringUtils.isNotBlank(taskOid)) { try { processDao.getWFService().transmitTask(taskOid, "user:" + userIds); } catch (PLException vciError) { throw WebUtil.getVciBaseException(vciError); } } } } @Override public void beginProxy(String userId, Date startDate, Date endDate, boolean isNowEnable) throws VciBaseException { processDao.beginProxy(userId, startDate, endDate, isNowEnable); } @Override public void endProxy() throws VciBaseException { processDao.endProxy(); } @Override public TasksAssignedInfo getProxy() throws VciBaseException { return processDao.getProxy(); } /** * 终止流程 * * @param executionId 流程执行主键 * @param note * @throws VciBaseException */ @Override public void endProcess(String executionId, String note) throws VciBaseException { WebUtil.alertNotNull(executionId, "流程执行实例的主键"); long currentTime = 0L; try { currentTime = platformClientUtil.getFrameworkService().getSystemTime(); } catch (Throwable e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[0], e); } DataGrid taskGrid = processDao.getUndoTaskByInstanceId(executionId, 0L); List workitemList =(List) taskGrid.getData(); callBefore(workitemList,"end",note,currentTime); //服务端都处理了,这里直接调用 processDao.endProcess(executionId); callAfter(null,null,workitemList,currentTime); } /** * 挂起流程 * * @param executionId 流程执行的主键 * @param note * @throws VciBaseException */ @Override public void suspendProcess(String executionId, String note) throws VciBaseException { WebUtil.alertNotNull(executionId, "流程执行实例的主键"); //将流程执行实例和当前待办任务都修改为挂起状态 //查询流程实例 Map conditionMap = new HashMap(); conditionMap.put("executionid", executionId.trim() + "*");//会有子流程 List workInstanceCbos = boService.queryCBO(processDao.getWorkIntanceBtmType(), conditionMap); if (workInstanceCbos == null || workInstanceCbos.size() == 0) { throw new VciBaseException(msgCodePrefix + "executionNotExist"); } //判断是否都是执行状态,前端的判断能被跳过 List needUpdateCbos = new ArrayList<>(); List workInstanceOids = new ArrayList(); for (BusinessObject cbo : workInstanceCbos) { if (!cbo.lcStatus.equalsIgnoreCase("Executing")) { throw new VciBaseException(msgCodePrefix + "processNotExecutionStatus"); } needUpdateCbos.add(cbo); workInstanceOids.add(ObjectTool.getBOAttributeValue(cbo,"executionid")); } //找相关的流程任务对象,并且是正在执行中的 conditionMap.put("executionid", QueryOptionConstant.IN + "(" + WebUtil.toInSql(workInstanceOids.toArray(new String[0])) + ")"); conditionMap.put("lcstatus", "Executing"); List workItemCbos = boService.queryCBO(processDao.getWorkitemBtmType(), conditionMap); if (workItemCbos != null && workItemCbos.size() > 0) { needUpdateCbos.addAll(workItemCbos); } long currentTime = 0L; try { currentTime = platformClientUtil.getFrameworkService().getSystemTime(); } catch (Throwable e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[0], e); } List mapList = boService.cbos2Map(workItemCbos); callBefore(mapList,"suspend",note,currentTime); try { lifeCycleService.transCboStatus(needUpdateCbos, "Suspended"); } catch (Exception e) { throw new VciBaseException("挂起流程时,批量跃迁生命周期状态失败!", new Object[]{}, e); } callAfter(null,null,mapList,currentTime); } /** * 恢复流程 * @param executionId 流程主键 * @throws VciBaseException */ @Override public void resumeProcess(String executionId) throws VciBaseException { WebUtil.alertNotNull(executionId, "流程执行实例的主键"); //将流程执行实例和当前待办任务都修改为挂起状态 //查询流程实例 Map conditionMap = new HashMap(); conditionMap.put("executionid", executionId.trim() + "*");//会有子流程 List workInstanceCbos = boService.queryCBO(processDao.getWorkIntanceBtmType(), conditionMap); if (workInstanceCbos == null || workInstanceCbos.size() == 0) { throw new VciBaseException(msgCodePrefix + "executionNotExist"); } //判断是否都是执行状态,前端的判断能被跳过 List needUpdateCbos = new ArrayList<>(); List workInstanceOids = new ArrayList(); for (BusinessObject cbo : workInstanceCbos) { if (!cbo.lcStatus.equalsIgnoreCase("Suspended")) { throw new VciBaseException(msgCodePrefix + "processNotSuspendedStatus"); } needUpdateCbos.add(cbo); workInstanceOids.add(cbo.oid); } //找相关的流程任务对象,并且是正在执行中的 conditionMap.put("executionid", QueryOptionConstant.IN + "(" + WebUtil.toInSql(workInstanceOids.toArray(new String[0])) + ")"); conditionMap.put("lcstatus", "Suspended"); List workItemCbos = boService.queryCBO(processDao.getWorkitemBtmType(), conditionMap); if (workItemCbos != null && workItemCbos.size() > 0) { needUpdateCbos.addAll(workItemCbos); } long currentTime = 0L; try { currentTime = platformClientUtil.getFrameworkService().getSystemTime(); } catch (Throwable e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[0], e); } callBefore(null,"resume","",currentTime); try { lifeCycleService.transCboStatus(needUpdateCbos, "Executing"); } catch (Exception e) { throw new VciBaseException("恢复流程时,批量跃迁生命周期状态失败!", new Object[]{}, e); } callAfter(null,boService.cbos2Map(workItemCbos),null,currentTime); } /** * 发起流程时校验属性是否符合要求 * * @param oids 主键 * @param btmType 业务类型 * @param attributes 属性名,逗号分隔 * @param attributeValues 属性的值 * @param primaryKeyName 主键的字段名 * @throws VciBaseException */ @Override public void checkAttributesOnStartProcess(String oids, String btmType, String attributes, String attributeValues, String primaryKeyName) throws VciBaseException { WebUtil.alertNotNull(oids, "校验数据的主键", btmType, "业务类型", attributeValues, "要校验的属性值"); if (StringUtils.isBlank(primaryKeyName)) { primaryKeyName = "oid"; } if (StringUtils.isBlank(attributes)) { attributes = "lcstatus"; } oids = WebUtil.removeComma(oids); attributes = WebUtil.removeComma(attributes); attributeValues = WebUtil.removeComma(attributeValues); if (attributes.indexOf(",") > -1) { if (StringUtils.countMatches(attributes, ",") != StringUtils.countMatches(attributeValues, ",")) { throw new VciBaseException("要校验的数据的属性名和属性的值长度不相等"); } } Map conditionMap = new HashMap(); conditionMap.put(primaryKeyName, QueryOptionConstant.IN + "(" + WebUtil.toInSql(oids) + ")"); String[] attributeArray = attributes.split(","); String[] attributeValueArray = attributeValues.split(","); for (int i = 0; i < attributeArray.length; i++) { String attr = attributeArray[i]; String attrValue = attributeValueArray[i].trim(); if (attrValue.indexOf("#") > -1) { conditionMap.put(attr, QueryOptionConstant.IN + "(" + WebUtil.toInSql(attrValue.replace("#", ","))); } else { conditionMap.put(attr, attributeValueArray[i].trim()); } } List causeList = Arrays.asList(new String[]{primaryKeyName}); List cbos = boService.queryCBO(btmType, conditionMap, null, causeList); if (cbos == null || cbos.size() == 0) { throw new VciBaseException("发起流程的业务数据全部不符合要求"); } Set oidSet = new HashSet(); String[] oidArray = oids.split(","); for (String oid : oidArray) { oidSet.add(oid); } for (BusinessObject cbo : cbos) { if (oidSet.contains(ObjectTool.getBOAttributeValue(cbo,primaryKeyName))) { oidSet.remove(ObjectTool.getBOAttributeValue(cbo,primaryKeyName)); } } if (oidSet.size() > 0) { throw new VciBaseException("发起流程的业务数据有" + oidSet.size() + "不符合要求"); } } /** * 批量终止流程 * * @param executionIds 流程的执行主键 * @param note 终止原因 * @throws VciBaseException */ @Override public void batchEndProcess(Collection executionIds, String note) throws VciBaseException { WebUtil.alertNotNull(executionIds,"流程执行主键信息"); for(String executionId: executionIds){ endProcess(executionId,note); } } /** * 添加流程审批意见文件 * * @param taskOids 流程任务的主键 * @param file 文件的数据 * @param originalFilename 文件的名称 * @throws VciBaseException 在查询流程任务的信息或者上传文件错误时会抛出异常 */ @Override public void uploadAuditSuggestFile(String taskOids, MultipartFile file, String originalFilename) throws VciBaseException { WebUtil.alertNotNull(taskOids, "流程任务主键", originalFilename, "文件名称"); if (file == null || file.getSize() == 0) { throw new VciBaseException("流程审批意见的文件内容为空"); } DataGrid dataGrid = processDefineService.getDataInProcess(taskOids, null, ""); if (dataGrid == null || CollectionUtils.isEmpty(dataGrid.getData())) { throw new VciBaseException("流程的业务数据是空的,数据错误"); } String btwName = ""; List businessDataOidList = new ArrayList(); List businessDataList = (List) dataGrid.getData(); for (Map businessData : businessDataList) { if (StringUtils.isBlank(btwName)) { btwName = (String) businessData.get("btmname"); } businessDataOidList.add((String) businessData.get("oid")); } String fileExtension = ""; if (originalFilename.contains(".")) { String temp = originalFilename.substring(0, originalFilename.lastIndexOf(".")); fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); originalFilename = temp; } for (String oid : businessDataOidList) { VciFileObjectDTO fileObjectDTO = new VciFileObjectDTO(); fileObjectDTO.setName(originalFilename); fileObjectDTO.setFileExtension(fileExtension); fileObjectDTO.setFileDocClassify("processAuditSuggest"); fileObjectDTO.setFileDocClassifyName("流程审批意见"); fileObjectDTO.setOwnBtmname(btwName); fileObjectDTO.setOwnbizOid(oid); fileObjectDTO.setSecretGrade(DataSecretEnum.NONE.getValue()); fileService.uploadFile(file, fileObjectDTO); } } }