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.workflow.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<String, List<ProcessUserVO>> processNodeUsers,
|
Map<String, String> 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<ProcessNodeVO> 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<ProcessUserVO> 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<String, String> conditionMap = WebUtil.getOidQuery(config.getOids());
|
conditionMap.put(WebBoServiceI.QUERY_FILTER_SECRET, "false");
|
conditionMap.put(WebBoServiceI.QUERY_FILTER_DATARIGHT, "false");
|
List<BusinessObject> 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 platformlt_" + processDao.getTaskDataLink() + " where oid " + conditionMap.get("oid").replace("\\IN", " in ") + ")");
|
List<BusinessObject> 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.revisionid;
|
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<Map> 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<Map> newWorkItemList,List<Map> 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<Map>)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<String, String> varMap) {
|
List<MapTransfersInfo> mapTransfersInfos = new ArrayList<MapTransfersInfo>();
|
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<ProcessUserVO> 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<ProcessUserVO> 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<ProcessTaskVO> 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<ProcessOutcomeVO> 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<String, List<ProcessUserVO>> 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<String, String> conditionMap = new HashMap<String, String>();
|
conditionMap.put("f_btwname", processDao.getWorkitemBtmType());
|
conditionMap.put("f_oid", QueryOptionConstant.IN + "(" + WebUtil.toInSql(taskIds) + ")");
|
List<LinkObject> 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<Map> 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.getWorkService().transmitTask(taskOid, "user:" + userIds, getUserEntityInfo());
|
} 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<Map> workitemList =(List<Map>) 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<String, String> conditionMap = new HashMap<String, String>();
|
conditionMap.put("executionid", executionId.trim() + "*");//会有子流程
|
List<BusinessObject> workInstanceCbos = boService.queryCBO(processDao.getWorkIntanceBtmType(), conditionMap);
|
if (workInstanceCbos == null || workInstanceCbos.size() == 0) {
|
throw new VciBaseException(msgCodePrefix + "executionNotExist");
|
}
|
//判断是否都是执行状态,前端的判断能被跳过
|
List<BusinessObject> needUpdateCbos = new ArrayList<>();
|
List<String> workInstanceOids = new ArrayList<String>();
|
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<BusinessObject> 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<Map> 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<String, String> conditionMap = new HashMap<String, String>();
|
conditionMap.put("executionid", executionId.trim() + "*");//会有子流程
|
List<BusinessObject> workInstanceCbos = boService.queryCBO(processDao.getWorkIntanceBtmType(), conditionMap);
|
if (workInstanceCbos == null || workInstanceCbos.size() == 0) {
|
throw new VciBaseException(msgCodePrefix + "executionNotExist");
|
}
|
//判断是否都是执行状态,前端的判断能被跳过
|
List<BusinessObject> needUpdateCbos = new ArrayList<>();
|
List<String> workInstanceOids = new ArrayList<String>();
|
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<BusinessObject> 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<String, String> conditionMap = new HashMap<String, String>();
|
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<String> causeList = Arrays.asList(new String[]{primaryKeyName});
|
List<BusinessObject> cbos = boService.queryCBO(btmType, conditionMap, null, causeList);
|
if (cbos == null || cbos.size() == 0) {
|
throw new VciBaseException("发起流程的业务数据全部不符合要求");
|
}
|
Set<String> oidSet = new HashSet<String>();
|
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<String> 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<String> businessDataOidList = new ArrayList<String>();
|
List<Map> businessDataList = (List<Map>) 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);
|
}
|
}
|
|
}
|