1.谐波普测流程相关调整

This commit is contained in:
cdf
2024-04-02 16:23:10 +08:00
parent 40bc9e57f3
commit 8a416bab4d
26 changed files with 2364 additions and 75 deletions

View File

@@ -103,4 +103,7 @@ public interface RGeneralSurveyPlanPOService extends IMppService<RGeneralSurveyP
* @Date: 2023/3/15
*/
RSurveyCycleVO addPlanCycle(Integer cycleNum);
Boolean submitAuditUser(RGeneralSurveyPlanAuditUserParam rGeneralSurveyPlanAuditUserParam);
}

View File

@@ -2,10 +2,14 @@ package com.njcn.process.service.flowable;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.process.pojo.dto.flowable.FlowProcDefDto;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
/**
@@ -51,4 +55,36 @@ public interface IFlowDefinitionService {
HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId);
/**
* 流程定义列表
*
* @param pageNum 当前页码
* @param pageSize 每页条数
* @return 流程定义分页列表数据
*/
Page<FlowProcDefDto> list(String name, Integer pageNum, Integer pageSize);
/**
* 导入流程文件
* 当每个key的流程第一次部署时指定版本为1。对其后所有使用相同key的流程定义
* 部署时版本会在该key当前已部署的最高版本号基础上加1。key参数用于区分流程定义
* @param name
* @param category
* @param in
*/
void importFile(String name, String category, InputStream in);
/**
* 读取xml
* @param deployId
* @return
*/
String readXml(String deployId) throws IOException;
Boolean assFormWithDeploy(String deployId,String formId);
}

View File

@@ -0,0 +1,55 @@
package com.njcn.process.service.flowable;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
import org.flowable.engine.history.HistoricProcessInstance;
import java.util.Map;
/**
* @author Tony
* @date 2021-04-03 14:40
*/
public interface IFlowInstanceService {
/**
* 结束流程实例
*
* @param vo
*/
void stopProcessInstance(FlowTaskVo vo);
/**
* 激活或挂起流程实例
*
* @param state 状态
* @param instanceId 流程实例ID
*/
void updateState(Integer state, String instanceId);
/**
* 删除流程实例ID
*
* @param instanceId 流程实例ID
* @param deleteReason 删除原因
*/
void delete(String instanceId, String deleteReason);
/**
* 根据实例ID查询历史实例数据
*
* @param processInstanceId
* @return
*/
HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId);
/**
* 根据流程定义ID启动流程实例
*
* @param procDefId 流程定义Id
* @param variables 流程变量
* @return
*/
String startProcessInstanceById(String procDefId, Map<String, Object> variables);
}

View File

@@ -2,7 +2,10 @@ package com.njcn.process.service.flowable;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.process.pojo.dto.flowable.FlowTaskDto;
import com.njcn.process.pojo.vo.flowable.FlowQueryVo;
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
import org.flowable.task.api.Task;
@@ -36,6 +39,14 @@ public interface IFlowTaskService {
Boolean complete(FlowTaskVo taskVo);
/**
* 给下一个任务指定执行人员
* @author cdf
* @date 2024/3/29
*/
Task toNextTaskUser(FlowTaskVo taskVo);
/**
* 获取任务
* @author cdf
@@ -44,5 +55,64 @@ public interface IFlowTaskService {
Task getTask(String proIndex);
/**
* 我发起的流程
* @param queryVo 请求参数
* @return
*/
Page<FlowTaskDto> myProcess(FlowQueryVo queryVo);
/**
* 已办任务列表
*
* @param queryVo 请求参数
* @return
*/
Page<FlowTaskDto> finishedList(FlowQueryVo queryVo);
/**
* 代办任务列表
*
* @param queryVo 请求参数
* @return
*/
Page<FlowTaskDto> todoList(FlowQueryVo queryVo);
/**
* 获取流程变量
* @param taskId
* @return
*/
Map<String, Object> processVariables(String taskId);
/**
* 流程历史流转记录
*
* @param procInsId 流程实例Id
* @return
*/
Map<String, Object> flowRecord(String procInsId,String deployId);
/**
* 取消申请
* 目前实现方式: 直接将当前流程变更为已完成
* @param flowTaskVo
* @return
*/
Boolean stopProcess(FlowTaskVo flowTaskVo);
/**
* 驳回任务
*
* @param flowTaskVo
*/
void taskReject(FlowTaskVo flowTaskVo);
}

View File

@@ -1,8 +1,10 @@
package com.njcn.process.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -15,22 +17,28 @@ import com.njcn.minioss.bo.MinIoUploadResDTO;
import com.njcn.oss.constant.OssPath;
import com.njcn.oss.enums.OssResponseEnum;
import com.njcn.oss.utils.FileStorageUtil;
import com.njcn.process.mapper.RGeneralSurveyPlanDetailMapper;
import com.njcn.process.mapper.RGeneralSurveyPlanPOMapper;
import com.njcn.process.mapper.RSurveyCycleMapper;
import com.njcn.process.enums.AuditProcessEnum;
import com.njcn.process.enums.FlowComment;
import com.njcn.process.mapper.*;
import com.njcn.process.pojo.param.*;
import com.njcn.process.pojo.po.RGeneralSurveyPlanDetail;
import com.njcn.process.pojo.po.RGeneralSurveyPlanPO;
import com.njcn.process.pojo.po.RSurveyCyclePO;
import com.njcn.process.pojo.po.RSurveyPlanConfigPO;
import com.njcn.process.pojo.po.*;
import com.njcn.process.pojo.vo.*;
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
import com.njcn.process.service.RGeneralSurveyPlanDetailService;
import com.njcn.process.service.RGeneralSurveyPlanPOService;
import com.njcn.process.service.flowable.IFlowDefinitionService;
import com.njcn.process.service.flowable.IFlowTaskService;
import com.njcn.process.service.impl.flowable.FlowDefinitionServiceImpl;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.api.UserFeignClient;
import com.njcn.user.pojo.po.Dept;
import com.njcn.user.pojo.po.User;
import com.njcn.user.pojo.vo.PvTerminalTreeVO;
import com.njcn.web.utils.RequestUtil;
import liquibase.pro.packaged.S;
import lombok.RequiredArgsConstructor;
import org.flowable.task.api.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -40,6 +48,7 @@ import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -64,6 +73,16 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
private final RSurveyCycleMapper rSurveyCycleMapper;
private final RSurveyPlanConfigService rSurveyPlanConfigService;
private final IFlowDefinitionService iFlowDefinitionService;
private final IFlowTaskService iFlowTaskService;
private final UserFeignClient userFeignClient;
private final FlowableAssMapper flowableAssMapper;
private final FlowFormAssMapper flowFormAssMapper;
/**
* @param rGeneralSurveyPlanAddParm
@@ -88,20 +107,23 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
RSurveyCyclePO rSurveyCyclePO = rSurveyCycleMapper.selectOne(rSurveyCyclePOQueryWrapper);
rGeneralSurveyPlanPO.setCycleId(rSurveyCyclePO.getId());
String deptIndex = RequestUtil.getDeptIndex();
Dept data = deptFeignClient.getDeptById(deptIndex).getData();
rGeneralSurveyPlanPO.setCheckPerson(data.getPid());
rGeneralSurveyPlanPO.setCreatePerson(RequestUtil.getUserIndex());
int count = this.count(new LambdaQueryWrapper<RGeneralSurveyPlanPO>()
.eq(RGeneralSurveyPlanPO::getPlanNo, rGeneralSurveyPlanAddParm.getPlanNo())
);
boolean b;
if (count > 0) {
b = this.updateByMultiId(rGeneralSurveyPlanPO);
RGeneralSurveyPlanPO generalSurveyPlanPO = this.getOne(new LambdaQueryWrapper<RGeneralSurveyPlanPO>()
.eq(RGeneralSurveyPlanPO::getPlanNo, rGeneralSurveyPlanAddParm.getPlanNo()));
rGeneralSurveyPlanPO.setStatus(AuditProcessEnum.New.getStatus());
if (Objects.isNull(generalSurveyPlanPO)) {
this.save(rGeneralSurveyPlanPO);
} else {
/*todo 后期与工作流绑定*/
rGeneralSurveyPlanPO.setStatus(0);
b = this.save(rGeneralSurveyPlanPO);
if(rGeneralSurveyPlanPO.getStatus() == AuditProcessEnum.New.getStatus() || rGeneralSurveyPlanPO.getStatus() == AuditProcessEnum.AuditRefuse.getStatus()){
this.updateByMultiId(rGeneralSurveyPlanPO);
}else {
throw new BusinessException("存在相同普测计划编号,请勿重复新建");
}
}
QueryWrapper<RGeneralSurveyPlanDetail> queryWrapper = new QueryWrapper();
@@ -109,7 +131,7 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
rGeneralSurveyPlanDetailService.remove(queryWrapper);
List<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetailList = new ArrayList<>();
SubstationParam param =new SubstationParam();
SubstationParam param = new SubstationParam();
param.setPowerIds(rGeneralSurveyPlanAddParm.getSubIds());
List<SubGetBase> stationList = commTerminalGeneralClient.tagOrIdGetSub(param).getData();
for (SubGetBase stat : stationList) {
@@ -128,8 +150,9 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
rGeneralSurveyPlanDetail.setVoltageLevel(stat.getVoltageLevel());
rGeneralSurveyPlanDetailList.add(rGeneralSurveyPlanDetail);
}
boolean b1 = rGeneralSurveyPlanDetailService.saveOrUpdateBatchByMultiId(rGeneralSurveyPlanDetailList, 500);
return b && b1;
rGeneralSurveyPlanDetailService.saveOrUpdateBatchByMultiId(rGeneralSurveyPlanDetailList, 500);
return true;
}
/**
@@ -145,13 +168,24 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
IPage<RGeneralSurveyPlanPO> page = new Page<>(rGeneralSurveyPlanQueryParm.getCurrentPage(), rGeneralSurveyPlanQueryParm.getPageSize());
IPage<RGeneralSurveyPlanVO> returnpage = new Page<>(rGeneralSurveyPlanQueryParm.getCurrentPage(), rGeneralSurveyPlanQueryParm.getPageSize());
String loginUserDept = RequestUtil.getDeptIndex();
String loginUsrId = RequestUtil.getUserIndex();
List<String> childrenDeptIds = deptFeignClient.getDepSonIdtByDeptId(loginUserDept).getData();
childrenDeptIds = childrenDeptIds.stream().filter(item -> !Objects.equals(item, loginUserDept)).distinct().collect(Collectors.toList());
List<User> userList = userFeignClient.getUserInfoByDeptIds(childrenDeptIds).getData();
User my = new User();
my.setId(loginUsrId);
my.setName(RequestUtil.getUserNickname());
userList.add(my);
List<String> userIds = userList.stream().map(User::getId).collect(Collectors.toList());
LambdaQueryWrapper<RGeneralSurveyPlanPO> queryWrapper = new LambdaQueryWrapper<>();
/*type=1新建页面查看自己负责的计划type=2审核页面审核者==当前用户;结果页面:查看自己负责的计划*/
if (type == "1" || type == "3") {
queryWrapper.eq(RGeneralSurveyPlanPO::getCreatePerson, RequestUtil.getUserIndex());
queryWrapper.in(RGeneralSurveyPlanPO::getCreatePerson, userIds);
}
if (type == "2") {
queryWrapper.eq(RGeneralSurveyPlanPO::getCheckPerson, RequestUtil.getDeptIndex());
queryWrapper.eq(RGeneralSurveyPlanPO::getCheckPerson, loginUsrId);
}
if (!StringUtils.isEmpty(rGeneralSurveyPlanQueryParm.getOrgNo())) {
List<String> data = deptFeignClient.getDepSonIdtByDeptId(rGeneralSurveyPlanQueryParm.getOrgNo()).getData();
@@ -180,10 +214,7 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
//部门处理根据部门code取名称
List<PvTerminalTreeVO> dept = deptFeignClient.allDeptList().getData();
Map<String, String> pvTerminalTreeVOMap = dept.stream().
collect(Collectors.
toMap(PvTerminalTreeVO::getId,
PvTerminalTreeVO::getName));
Map<String, String> pvTerminalTreeVOMap = dept.stream().collect(Collectors.toMap(PvTerminalTreeVO::getId, PvTerminalTreeVO::getName));
List<String> collect = rGeneralSurveyPlanPOS.stream().map(RGeneralSurveyPlanPO::getPlanNo).collect(Collectors.toList());
@@ -191,6 +222,12 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
lambdaQueryWrapper.in(RGeneralSurveyPlanDetail::getPlanNo, collect);
List<RGeneralSurveyPlanDetail> rGeneralSurveyPlanDetails = rGeneralSurveyPlanDetailMapper.selectList(lambdaQueryWrapper);
List<RGeneralSurveyPlanVO> rGeneralSurveyPlanVOList = new ArrayList<>();
Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
List<String> checkIds = rGeneralSurveyPlanPOS.stream().map(RGeneralSurveyPlanPO::getCheckPerson).filter(Objects::nonNull).collect(Collectors.toList());
List<User> checkUserList = userFeignClient.getUserByIdList(checkIds).getData();
Map<String, User> checkMap = checkUserList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
rGeneralSurveyPlanPOS.forEach(temp -> {
RGeneralSurveyPlanVO rGeneralSurveyPlanVO = new RGeneralSurveyPlanVO();
BeanUtils.copyProperties(temp, rGeneralSurveyPlanVO);
@@ -199,22 +236,14 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
map(RGeneralSurveyPlanDetail::getSubId).collect(Collectors.toList());
rGeneralSurveyPlanVO.setSubCount(collect1.size());
rGeneralSurveyPlanVO.setSubIds(collect1);
rGeneralSurveyPlanVO.setIsFileUpload(ObjectUtil.isNull(temp.getIsFileUpload()) ? 0 : temp.getIsFileUpload());
/*
long Subcount = rGeneralSurveyPlanDetails.stream ( ).
filter (surveyPlanDetail -> Objects.equals (surveyPlanDetail.getPlanNo ( ), temp.getPlanNo ( ))).
map (RGeneralSurveyPlanDetail::getSubId).distinct ( ).count ( );*/
// rGeneralSurveyPlanVO.setBusCount (Busbarcount);
// List<RGeneralSurveyPlanVO.RGeneralSurveyPlanDetailVO> collect1 = rGeneralSurveyPlanDetails.stream ( ).
// filter (surveyPlanDetail -> Objects.equals (surveyPlanDetail.getPlanNo ( ), temp.getPlanNo ( ))).
// map (surveyPlanDetail -> {
// RGeneralSurveyPlanVO.RGeneralSurveyPlanDetailVO rGeneralSurveyPlanDetailVO = new RGeneralSurveyPlanVO.RGeneralSurveyPlanDetailVO ( );
// BeanUtils.copyProperties (surveyPlanDetail, rGeneralSurveyPlanDetailVO);
// return rGeneralSurveyPlanDetailVO;
// }).collect (Collectors.toList ( ));
rGeneralSurveyPlanVO.setIsFileUpload(ObjectUtil.isNull(temp.getIsFileUpload()) ? 0 : temp.getIsFileUpload());
rGeneralSurveyPlanVO.setOrgName(pvTerminalTreeVOMap.get(temp.getOrgNo())); //单位名称
//
// rGeneralSurveyPlanVO.setRGeneralSurveyPlanDetailVOList (collect1);
rGeneralSurveyPlanVO.setCreatePersonName(userMap.get(temp.getCreatePerson()).getName());
if (StrUtil.isNotBlank(temp.getCheckPerson())) {
rGeneralSurveyPlanVO.setCheckPerson(checkMap.get(temp.getCheckPerson()).getName());
}
rGeneralSurveyPlanVOList.add(rGeneralSurveyPlanVO);
});
@@ -249,12 +278,13 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
filePath = filePath + fileStoragePath + "##" + OriginalFilename + ";";
fileCount++;
}
rGeneralSurveyPlanPO.setStatus(4);
rGeneralSurveyPlanPO.setFileCount(fileCount);
rGeneralSurveyPlanPO.setFilePath(filePath);
rGeneralSurveyPlanPO.setIsFileUpload(1);
rGeneralSurveyPlanPO.setUploadTime(new Date());
this.saveOrUpdateByMultiId(rGeneralSurveyPlanPO);
return result;
}
@@ -339,13 +369,13 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
case 1:
result = "待审核";
break;
case 2:
case 3:
result = "审核未通过";
break;
case 3:
case 4:
result = "已发布";
break;
case 4:
case 5:
result = "已完成";
break;
default:
@@ -401,13 +431,50 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
@Override
@Transactional(rollbackFor = {Exception.class})
public Boolean checkPlanAudit(RGeneralSurveyPlanChcekParm rGeneralSurveyPlanChcekParm) {
RGeneralSurveyPlanPO rGeneralSurveyPlanPO = this.lambdaQuery().eq(RGeneralSurveyPlanPO::getPlanNo,rGeneralSurveyPlanChcekParm.getPlanNo()).one();
if(rGeneralSurveyPlanPO.getStatus() != AuditProcessEnum.WaitAudit.getStatus()){
throw new BusinessException("当前流程非待审核状态");
}
boolean result = true;
UpdateWrapper<RGeneralSurveyPlanPO> updateWrapper = new UpdateWrapper();
updateWrapper.eq("plan_no", rGeneralSurveyPlanChcekParm.getPlanNo());
updateWrapper.set("check_comment", rGeneralSurveyPlanChcekParm.getCheckComment());
// updateWrapper.set ("check_person", rGeneralSurveyPlanChcekParm.getCheckPerson ( ));
updateWrapper.set("status", Objects.equals("1", rGeneralSurveyPlanChcekParm.getCheckResult()) ? 3 : 2);
updateWrapper.set("status", Objects.equals("1", rGeneralSurveyPlanChcekParm.getCheckResult()) ? AuditProcessEnum.Release.getStatus() : AuditProcessEnum.AuditRefuse.getStatus());
result = this.update(updateWrapper);
//处理流程
FlowableAss flowableAss = flowableAssMapper.selectOne(new LambdaQueryWrapper<FlowableAss>().eq(FlowableAss::getThsIndex,rGeneralSurveyPlanChcekParm.getPlanNo()));
String auditResult = Objects.equals("1", rGeneralSurveyPlanChcekParm.getCheckResult()) ? "同意" : "拒绝";
if(Objects.equals("0", rGeneralSurveyPlanChcekParm.getCheckResult())){
//拒绝,则回退到申请步骤
Task task = iFlowTaskService.getTask(flowableAss.getExecIndex());
FlowTaskVo flowTaskVo = new FlowTaskVo();
flowTaskVo.setTaskId(task.getId());
flowTaskVo.setComment(rGeneralSurveyPlanChcekParm.getCheckComment());
iFlowTaskService.taskReject(flowTaskVo);
}else {
Task task = iFlowTaskService.getTask(flowableAss.getExecIndex());
FlowTaskVo flowTaskVo = new FlowTaskVo();
flowTaskVo.setTaskId(task.getId());
flowTaskVo.setInstanceId(flowableAss.getExecIndex());
flowTaskVo.setComment(RequestUtil.getUserNickname() + auditResult+"编号为"+rGeneralSurveyPlanChcekParm.getPlanNo()+"的计划,结论:"+rGeneralSurveyPlanChcekParm.getCheckComment());
Map<String,Object> map = new HashMap<>();
map.put("auditFlag",1);
flowTaskVo.setVariables(map);
iFlowTaskService.complete(flowTaskVo);
}
return result;
}
@@ -538,7 +605,7 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
BeanUtils.copyProperties(temp, deptSubstationVO);
deptSubstationVO.setDisabled(true);
deptSubstationVO.setFlag(true);
SubstationParam param =new SubstationParam();
SubstationParam param = new SubstationParam();
param.setOrgIds(Arrays.asList(temp.getCode()));
List<SubGetBase> list1 = commTerminalGeneralClient.tagOrIdGetSub(param).getData();
List<DeptSubstationVO> children = deptSubstationVO.getChildren();
@@ -603,6 +670,70 @@ public class RGeneralSurveyPlanPOServiceImpl extends MppServiceImpl<RGeneralSurv
return rSurveyCycleVO;
}
@Override
public Boolean submitAuditUser(RGeneralSurveyPlanAuditUserParam rGeneralSurveyPlanAuditUserParam) {
String userId = RequestUtil.getUserIndex();
List<String> planIds = rGeneralSurveyPlanAuditUserParam.getPlanIds();
Integer count = this.lambdaQuery().in(RGeneralSurveyPlanPO::getPlanNo, planIds).eq(RGeneralSurveyPlanPO::getCreatePerson, userId).count();
if (count != planIds.size()) {
throw new BusinessException("只可以操作自己创建的计划!");
}
this.update(new LambdaUpdateWrapper<RGeneralSurveyPlanPO>()
.in(RGeneralSurveyPlanPO::getPlanNo, planIds)
.set(RGeneralSurveyPlanPO::getStatus, AuditProcessEnum.WaitAudit.getStatus()).set(RGeneralSurveyPlanPO::getCheckPerson, rGeneralSurveyPlanAuditUserParam.getAuditUser())
);
//绑定工作流
Map<String, Object> map = new HashMap<>();
//map.put("applyUser",userId);
for (String planId : planIds) {
//需要判断那些流程已经启动,已经启动的则为驳回后的再次提交审核
FlowableAss flowableAss = flowableAssMapper.selectOne(new LambdaQueryWrapper<FlowableAss>().eq(FlowableAss::getThsIndex,planId));
if(Objects.nonNull(flowableAss)){
//不为空则认为是驳回后的重新发起
Task task = iFlowTaskService.getTask(flowableAss.getExecIndex());
FlowTaskVo flowTaskVo = new FlowTaskVo();
flowTaskVo.setTaskId(task.getId());
flowTaskVo.setAssignee(userId);
flowTaskVo.setComment(RequestUtil.getUserNickname() + "重新发起普测计划申请");
iFlowTaskService.complete(flowTaskVo);
Task taskNext = iFlowTaskService.getTask(flowableAss.getExecIndex());
FlowTaskVo flowTaskVoNext = new FlowTaskVo();
flowTaskVoNext.setTaskId(taskNext.getId());
flowTaskVoNext.setAssignee(rGeneralSurveyPlanAuditUserParam.getAuditUser());
iFlowTaskService.toNextTaskUser(flowTaskVoNext);
}else {
//开始流程
FlowFormAss flowFormAss = flowFormAssMapper.selectOne(new LambdaQueryWrapper<FlowFormAss>().eq(FlowFormAss::getFormId,1));
if(Objects.isNull(flowFormAss)){
throw new BusinessException("当前功能未绑定流程,请先绑定流程");
}
String processId = iFlowDefinitionService.startProcessInstanceById(flowFormAss.getDefinitionId(), planId, map);
Task task = iFlowTaskService.getTask(processId);
FlowTaskVo flowTaskVo = new FlowTaskVo();
flowTaskVo.setTaskId(task.getId());
flowTaskVo.setInstanceId(processId);
flowTaskVo.setAssignee(RequestUtil.getUserIndex());
flowTaskVo.setComment(RequestUtil.getUserNickname() + "发起普测计划申请");
iFlowTaskService.complete(flowTaskVo);
Task taskNext = iFlowTaskService.getTask(processId);
FlowTaskVo flowTaskVoNext = new FlowTaskVo();
flowTaskVoNext.setTaskId(taskNext.getId());
flowTaskVoNext.setAssignee(rGeneralSurveyPlanAuditUserParam.getAuditUser());
iFlowTaskService.toNextTaskUser(flowTaskVoNext);
}
}
return true;
}
public List<DeptSubstationVO> recursion(DeptSubstationVO result, String orgdid) {
List<DeptSubstationVO> deptSubstationVOList = new ArrayList<>();
if (Objects.equals(result.getId(), orgdid)) {

View File

@@ -8,7 +8,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.PubUtils;
import com.njcn.process.factory.FlowServiceFactory;
import com.njcn.process.mapper.FlowFormAssMapper;
import com.njcn.process.mapper.FlowableAssMapper;
import com.njcn.process.pojo.dto.flowable.FlowProcDefDto;
import com.njcn.process.pojo.po.FlowFormAss;
import com.njcn.process.pojo.po.FlowableAss;
import com.njcn.process.service.flowable.IFlowDefinitionService;
import com.njcn.web.utils.RequestUtil;
@@ -53,6 +56,8 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
private final FlowableAssMapper flowableAssMapper;
private final FlowFormAssMapper flowFormAssMapper;
@@ -75,7 +80,7 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
// 设置流程发起人Id到流程中
identityService.setAuthenticatedUserId(RequestUtil.getUserIndex());
variables.put("INITIATOR", RequestUtil.getUserIndex());
//variables.put("applyUser", RequestUtil.getUserIndex());
ProcessInstance res = runtimeService.startProcessInstanceById(procDefId, variables);
FlowableAss flowableAss = new FlowableAss();
@@ -84,7 +89,7 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
flowableAss.setExecIndex(res.getProcessInstanceId());
flowableAssMapper.insert(flowableAss);
return res.getCallbackId();
return res.getProcessInstanceId();
} catch (Exception e) {
e.printStackTrace();
throw new BusinessException("开始流程出错!");
@@ -146,4 +151,103 @@ public class FlowDefinitionServiceImpl extends FlowServiceFactory implements IFl
return historicProcessInstance;
}
/**
* 流程定义列表
*
* @param pageNum 当前页码
* @param pageSize 每页条数
* @return 流程定义分页列表数据
*/
@Override
public Page<FlowProcDefDto> list(String name, Integer pageNum, Integer pageSize) {
// // 流程定义列表数据查询
// final ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
// if (StringUtils.isNotEmpty(name)) {
// processDefinitionQuery.processDefinitionNameLike(name);
// }
//// processDefinitionQuery.orderByProcessDefinitionKey().asc();
// page.setTotal(processDefinitionQuery.count());
// List<ProcessDefinition> processDefinitionList = processDefinitionQuery.listPage(pageSize * (pageNum - 1), pageSize);
//
// List<FlowProcDefDto> dataList = new ArrayList<>();
// for (ProcessDefinition processDefinition : processDefinitionList) {
// String deploymentId = processDefinition.getDeploymentId();
// Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
// FlowProcDefDto reProcDef = new FlowProcDefDto();
// BeanUtils.copyProperties(processDefinition, reProcDef);
// SysForm sysForm = sysDeployFormService.selectSysDeployFormByDeployId(deploymentId);
// if (Objects.nonNull(sysForm)) {
// reProcDef.setFormName(sysForm.getFormName());
// reProcDef.setFormId(sysForm.getFormId());
// }
// // 流程定义时间
// reProcDef.setDeploymentTime(deployment.getDeploymentTime());
// dataList.add(reProcDef);
// }
Page<FlowProcDefDto> pageResult = flowableAssMapper.selectDeployList(new Page<>(pageNum,pageSize),name);
// 加载挂表单
/* for (FlowProcDefDto procDef : dataList) {
SysForm sysForm = sysDeployFormService.selectSysDeployFormByDeployId(procDef.getDeploymentId());
if (Objects.nonNull(sysForm)) {
procDef.setFormName(sysForm.getFormName());
procDef.setFormId(sysForm.getFormId());
}
}*/
return pageResult;
}
/**
* 导入流程文件
*
* 当每个key的流程第一次部署时指定版本为1。对其后所有使用相同key的流程定义
* 部署时版本会在该key当前已部署的最高版本号基础上加1。key参数用于区分流程定义
* @param name
* @param category
* @param in
*/
@Override
public void importFile(String name, String category, InputStream in) {
Deployment deploy = repositoryService.createDeployment().addInputStream(name + BPMN_FILE_SUFFIX, in).name(name).category(category).deploy();
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();
repositoryService.setProcessDefinitionCategory(definition.getId(), category);
}
/**
* 读取xml
*
* @param deployId
* @return
*/
@Override
public String readXml(String deployId) throws IOException {
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
InputStream inputStream = repositoryService.getResourceAsStream(definition.getDeploymentId(), definition.getResourceName());
String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
return result;
}
@Override
public Boolean assFormWithDeploy(String deployId, String formId) {
LambdaQueryWrapper<FlowFormAss> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(FlowFormAss::getDefinitionId,deployId);
FlowFormAss flowFormAss = flowFormAssMapper.selectOne(lambdaQueryWrapper);
FlowFormAss po = new FlowFormAss();
po.setDefinitionId(deployId);
po.setFormId(formId);
if(Objects.isNull(flowFormAss)){
flowFormAssMapper.insert(po);
}else {
flowFormAssMapper.update(po,new LambdaQueryWrapper<FlowFormAss>().eq(FlowFormAss::getDefinitionId,deployId));
}
return true;
}
}

View File

@@ -0,0 +1,121 @@
package com.njcn.process.service.impl.flowable;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.process.factory.FlowServiceFactory;
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
import com.njcn.process.service.flowable.IFlowInstanceService;
import com.njcn.web.utils.RequestUtil;
import liquibase.pro.packaged.S;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.engine.history.HistoricProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
import java.util.Objects;
/**
* <p>工作流流程实例管理<p>
*
* @author Tony
* @date 2021-04-03
*/
@Service
@Slf4j
public class FlowInstanceServiceImpl extends FlowServiceFactory implements IFlowInstanceService {
/**
* 结束流程实例
*
* @param vo
*/
@Override
public void stopProcessInstance(FlowTaskVo vo) {
String taskId = vo.getTaskId();
}
/**
* 激活或挂起流程实例
*
* @param state 状态
* @param instanceId 流程实例ID
*/
@Override
public void updateState(Integer state, String instanceId) {
// 激活
if (state == 1) {
runtimeService.activateProcessInstanceById(instanceId);
}
// 挂起
if (state == 2) {
runtimeService.suspendProcessInstanceById(instanceId);
}
}
/**
* 删除流程实例ID
*
* @param instanceId 流程实例ID
* @param deleteReason 删除原因
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(String instanceId, String deleteReason) {
// 查询历史数据
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(instanceId);
if (historicProcessInstance.getEndTime() != null) {
historyService.deleteHistoricProcessInstance(historicProcessInstance.getId());
return;
}
// 删除流程实例
runtimeService.deleteProcessInstance(instanceId, deleteReason);
// 删除历史流程实例
historyService.deleteHistoricProcessInstance(instanceId);
}
/**
* 根据实例ID查询历史实例数据
*
* @param processInstanceId
* @return
*/
@Override
public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) {
HistoricProcessInstance historicProcessInstance =
historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if (Objects.isNull(historicProcessInstance)) {
throw new FlowableObjectNotFoundException("流程实例不存在: " + processInstanceId);
}
return historicProcessInstance;
}
/**
* 根据流程定义ID启动流程实例
*
* @param procDefId 流程定义Id
* @param variables 流程变量
* @return
*/
@Override
public String startProcessInstanceById(String procDefId, Map<String, Object> variables) {
try {
// 设置流程发起人Id到流程中
String userId = RequestUtil.getUserIndex();
// identityService.setAuthenticatedUserId(userId.toString());
variables.put("initiator",userId);
variables.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", true);
runtimeService.startProcessInstanceById(procDefId, variables);
return "流程启动成功";
} catch (Exception e) {
e.printStackTrace();
return "流程启动错误";
}
}
}

View File

@@ -2,13 +2,26 @@ package com.njcn.process.service.impl.flowable;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.process.enums.FlowComment;
import com.njcn.process.factory.FlowServiceFactory;
import com.njcn.process.pojo.dto.FlowViewerDto;
import com.njcn.process.pojo.dto.flowable.FlowCommentDto;
import com.njcn.process.pojo.dto.flowable.FlowTaskDto;
import com.njcn.process.pojo.vo.flowable.FlowQueryVo;
import com.njcn.process.pojo.vo.flowable.FlowTaskVo;
import com.njcn.process.service.flowable.IFlowTaskService;
import com.njcn.process.utils.FlowableUtils;
import com.njcn.user.api.UserFeignClient;
import com.njcn.user.pojo.po.User;
import com.njcn.user.pojo.vo.UserVO;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
@@ -46,6 +59,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author Tony
@@ -53,8 +67,11 @@ import java.util.stream.Collectors;
**/
@Service
@Slf4j
@RequiredArgsConstructor
public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTaskService {
private final UserFeignClient userFeignClient;
@Override
public Boolean getNextFlowNodeByStart(FlowTaskVo flowTaskVo) {
@@ -124,16 +141,28 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
}
if (DelegationState.PENDING.equals(task.getDelegationState())) {
//taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.DELEGATE.getType(), taskVo.getComment());
//taskService.resolveTask(taskVo.getTaskId(), taskVo.getVariables());
taskService.resolveTask(taskVo.getTaskId(), taskVo.getVariables());
} else {
//taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getComment());
taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getComment());
//Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
taskService.setAssignee(taskVo.getTaskId(), "1");
if(StrUtil.isNotBlank(taskVo.getAssignee())){
taskService.setAssignee(taskVo.getTaskId(), taskVo.getAssignee());
}
taskService.complete(taskVo.getTaskId(), taskVo.getVariables());
}
return true;
}
@Override
public Task toNextTaskUser(FlowTaskVo taskVo) {
Task task = taskService.createTaskQuery().taskId(taskVo.getTaskId()).singleResult();
if (Objects.isNull(task)) {
throw new BusinessException("任务不存在");
}
taskService.setAssignee(taskVo.getTaskId(), taskVo.getAssignee());
return task;
}
@Override
public Task getTask(String proIndex) {
return taskService.createTaskQuery()
@@ -141,4 +170,512 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
}
/**
* 我发起的流程
*
* @param queryVo 请求参数
* @return
*/
@Override
public Page<FlowTaskDto> myProcess(FlowQueryVo queryVo) {
Page<FlowTaskDto> page = new Page<>();
String userId = RequestUtil.getUserIndex();
HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
.startedBy(userId)
.orderByProcessInstanceStartTime()
.desc();
List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.listPage(queryVo.getPageSize() * (queryVo.getPageNum() - 1), queryVo.getPageSize());
page.setTotal(historicProcessInstanceQuery.count());
List<FlowTaskDto> flowList = new ArrayList<>();
for (HistoricProcessInstance hisIns : historicProcessInstances) {
FlowTaskDto flowTask = new FlowTaskDto();
flowTask.setCreateTime(hisIns.getStartTime());
flowTask.setFinishTime(hisIns.getEndTime());
flowTask.setProcInsId(hisIns.getId());
// 计算耗时
if (Objects.nonNull(hisIns.getEndTime())) {
long time = hisIns.getEndTime().getTime() - hisIns.getStartTime().getTime();
flowTask.setDuration(getDate(time));
} else {
long time = System.currentTimeMillis() - hisIns.getStartTime().getTime();
flowTask.setDuration(getDate(time));
}
// 流程定义信息
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(hisIns.getProcessDefinitionId())
.singleResult();
flowTask.setDeployId(pd.getDeploymentId());
flowTask.setProcDefName(pd.getName());
flowTask.setProcDefVersion(pd.getVersion());
flowTask.setCategory(pd.getCategory());
flowTask.setProcDefVersion(pd.getVersion());
// 当前所处流程
List<Task> taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).list();
if (CollectionUtils.isNotEmpty(taskList)) {
flowTask.setTaskId(taskList.get(0).getId());
flowTask.setTaskName(taskList.get(0).getName());
if (StringUtils.isNotBlank(taskList.get(0).getAssignee())) {
// 当前任务节点办理人信息
List<User> userList = userFeignClient.getUserByIdList(Stream.of(taskList.get(0).getAssignee()).collect(Collectors.toList())).getData();
if (CollectionUtil.isNotEmpty(userList)) {
flowTask.setAssigneeId(userList.get(0).getId());
flowTask.setAssigneeName(userList.get(0).getName());
flowTask.setAssigneeDeptName(Objects.nonNull(userList.get(0).getDeptId()) ? userList.get(0).getDeptId() : "");
}
}
} else {
List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(hisIns.getId()).orderByHistoricTaskInstanceEndTime().desc().list();
flowTask.setTaskId(historicTaskInstance.get(0).getId());
flowTask.setTaskName(historicTaskInstance.get(0).getName());
if (StringUtils.isNotBlank(historicTaskInstance.get(0).getAssignee())) {
// 当前任务节点办理人信息
UserVO userVO = userFeignClient.getUserById(historicTaskInstance.get(0).getAssignee()).getData();
if (Objects.nonNull(userVO)) {
flowTask.setAssigneeId(userVO.getId());
flowTask.setAssigneeName(userVO.getName());
flowTask.setAssigneeDeptName(Objects.nonNull(userVO.getDeptName()) ? userVO.getDeptName() : "");
}
}
}
flowList.add(flowTask);
}
page.setRecords(flowList);
return page;
}
/**
* 已办任务列表
*
* @param queryVo 请求参数
* @return
*/
@Override
public Page<FlowTaskDto> finishedList(FlowQueryVo queryVo) {
Page<FlowTaskDto> page = new Page<>();
String userId = RequestUtil.getUserIndex();
HistoricTaskInstanceQuery taskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
.includeProcessVariables()
.finished()
.taskAssignee(userId)
.orderByHistoricTaskInstanceEndTime()
.desc();
List<HistoricTaskInstance> historicTaskInstanceList = taskInstanceQuery.listPage(queryVo.getPageSize() * (queryVo.getPageNum() - 1), queryVo.getPageSize());
List<FlowTaskDto> hisTaskList = new ArrayList<>();
for (HistoricTaskInstance histTask : historicTaskInstanceList) {
FlowTaskDto flowTask = new FlowTaskDto();
// 当前流程信息
flowTask.setTaskId(histTask.getId());
// 审批人员信息
flowTask.setCreateTime(histTask.getCreateTime());
flowTask.setFinishTime(histTask.getEndTime());
flowTask.setDuration(getDate(histTask.getDurationInMillis()));
flowTask.setProcDefId(histTask.getProcessDefinitionId());
flowTask.setTaskDefKey(histTask.getTaskDefinitionKey());
flowTask.setTaskName(histTask.getName());
// 流程定义信息
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(histTask.getProcessDefinitionId())
.singleResult();
flowTask.setDeployId(pd.getDeploymentId());
flowTask.setProcDefName(pd.getName());
flowTask.setProcDefVersion(pd.getVersion());
flowTask.setProcInsId(histTask.getProcessInstanceId());
flowTask.setHisProcInsId(histTask.getProcessInstanceId());
// 流程发起人信息
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(histTask.getProcessInstanceId())
.singleResult();
List<User> userList = userFeignClient.getUserByIdList(Stream.of(historicProcessInstance.getStartUserId()).collect(Collectors.toList())).getData();
flowTask.setStartUserId(userList.get(0).getLoginName());
flowTask.setStartUserName(userList.get(0).getName());
flowTask.setStartDeptName(userList.get(0).getDeptId());
hisTaskList.add(flowTask);
}
page.setTotal(taskInstanceQuery.count());
page.setRecords(hisTaskList);
return page;
}
/**
* 代办任务列表
*
* @param queryVo 请求参数
* @return
*/
@Override
public Page<FlowTaskDto> todoList(FlowQueryVo queryVo) {
Page<FlowTaskDto> page = new Page<>();
// 只查看自己的数据
String userId = RequestUtil.getUserIndex();
UserVO sysUser = userFeignClient.getUserById(userId).getData();
TaskQuery taskQuery = taskService.createTaskQuery()
.active()
.includeProcessVariables()
.taskCandidateGroupIn(sysUser.getRoleList())
.taskCandidateOrAssigned(sysUser.getId())
.orderByTaskCreateTime().desc();
// TODO 传入名称查询不到数据?
// if (StringUtils.isNotBlank(queryVo.getName())){
// taskQuery.processDefinitionNameLike(queryVo.getName());
// }
page.setTotal(taskQuery.count());
List<Task> taskList = taskQuery.listPage(queryVo.getPageSize() * (queryVo.getPageNum() - 1), queryVo.getPageSize());
List<FlowTaskDto> flowList = new ArrayList<>();
for (Task task : taskList) {
FlowTaskDto flowTask = new FlowTaskDto();
// 当前流程信息
flowTask.setTaskId(task.getId());
flowTask.setTaskDefKey(task.getTaskDefinitionKey());
flowTask.setCreateTime(task.getCreateTime());
flowTask.setProcDefId(task.getProcessDefinitionId());
flowTask.setExecutionId(task.getExecutionId());
flowTask.setTaskName(task.getName());
// 流程定义信息
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(task.getProcessDefinitionId())
.singleResult();
flowTask.setDeployId(pd.getDeploymentId());
flowTask.setProcDefName(pd.getName());
flowTask.setProcDefVersion(pd.getVersion());
flowTask.setProcInsId(task.getProcessInstanceId());
// 流程发起人信息
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.singleResult();
UserVO startUser = userFeignClient.getUserById(historicProcessInstance.getStartUserId()).getData();
flowTask.setStartUserId(startUser.getId());
flowTask.setStartUserName(startUser.getName());
flowTask.setStartDeptName(Objects.nonNull(startUser.getDeptName()) ? startUser.getDeptName() : "");
flowList.add(flowTask);
}
page.setRecords(flowList);
return page;
}
/**
* 获取流程变量
*
* @param taskId
* @return
*/
@Override
public Map<String, Object> processVariables(String taskId) {
// HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
// .processInstanceId(task.getProcessInstanceId())
// .singleResult();
// SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId()));
// 流程变量
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().includeProcessVariables().finished().taskId(taskId).singleResult();
if (Objects.nonNull(historicTaskInstance)) {
return historicTaskInstance.getProcessVariables();
} else {
Map<String, Object> variables = taskService.getVariables(taskId);
return variables;
}
}
/**
* 流程历史流转记录
*
* @param procInsId 流程实例Id
* @return
*/
@Override
public Map<String, Object> flowRecord(String procInsId, String deployId) {
Map<String, Object> map = new HashMap<String, Object>();
if (StringUtils.isNotBlank(procInsId)) {
List<HistoricActivityInstance> list = historyService
.createHistoricActivityInstanceQuery()
.processInstanceId(procInsId)
.orderByHistoricActivityInstanceStartTime()
.desc().list();
List<FlowTaskDto> hisFlowList = new ArrayList<>();
for (HistoricActivityInstance histIns : list) {
// 展示开始节点
// if ("startEvent".equals(histIns.getActivityType())) {
// FlowTaskDto flowTask = new FlowTaskDto();
// // 流程发起人信息
// HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
// .processInstanceId(histIns.getProcessInstanceId())
// .singleResult();
// SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId()));
// flowTask.setTaskName(startUser.getNickName() + "(" + startUser.getDept().getDeptName() + ")发起申请");
// flowTask.setFinishTime(histIns.getEndTime());
// hisFlowList.add(flowTask);
// } else if ("endEvent".equals(histIns.getActivityType())) {
// FlowTaskDto flowTask = new FlowTaskDto();
// flowTask.setTaskName(StringUtils.isNotBlank(histIns.getActivityName()) ? histIns.getActivityName() : "结束");
// flowTask.setFinishTime(histIns.getEndTime());
// hisFlowList.add(flowTask);
// } else
if (StringUtils.isNotBlank(histIns.getTaskId())) {
FlowTaskDto flowTask = new FlowTaskDto();
flowTask.setTaskId(histIns.getTaskId());
flowTask.setTaskName(histIns.getActivityName());
flowTask.setCreateTime(histIns.getStartTime());
flowTask.setFinishTime(histIns.getEndTime());
if (StringUtils.isNotBlank(histIns.getAssignee())) {
UserVO sysUser = userFeignClient.getUserById(histIns.getAssignee()).getData();
flowTask.setAssigneeId(sysUser.getId());
flowTask.setAssigneeName(sysUser.getName());
flowTask.setDeptName(Objects.nonNull(sysUser.getDeptName()) ? sysUser.getDeptName() : "");
}
// 展示审批人员
List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(histIns.getTaskId());
StringBuilder stringBuilder = new StringBuilder();
for (HistoricIdentityLink identityLink : linksForTask) {
// 获选人,候选组/角色(多个)
if ("candidate".equals(identityLink.getType())) {
if (StringUtils.isNotBlank(identityLink.getUserId())) {
UserVO sysUser = userFeignClient.getUserById(identityLink.getUserId()).getData();
stringBuilder.append(sysUser.getName()).append(",");
}
if (StringUtils.isNotBlank(identityLink.getGroupId())) {
/* UserVO sysUser = userFeignClient.getUserById(identityLink.getUserId()).getData();
SysRole sysRole = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
stringBuilder.append(sysRole.getRoleName()).append(",");*/
}
}
}
if (StringUtils.isNotBlank(stringBuilder)) {
flowTask.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1));
}
flowTask.setDuration(histIns.getDurationInMillis() == null || histIns.getDurationInMillis() == 0 ? null : getDate(histIns.getDurationInMillis()));
// 获取意见评论内容
List<Comment> commentList = taskService.getProcessInstanceComments(histIns.getProcessInstanceId());
commentList.forEach(comment -> {
if (histIns.getTaskId().equals(comment.getTaskId())) {
flowTask.setComment(FlowCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build());
}
});
hisFlowList.add(flowTask);
}
}
map.put("flowList", hisFlowList);
}
// 第一次申请获取初始化表单
if (StringUtils.isNotBlank(deployId)) {
/* SysForm sysForm = sysInstanceFormService.selectSysDeployFormByDeployId(deployId);
if (Objects.isNull(sysForm)) {
return AjaxResult.error("请先配置流程表单");
}
map.put("formData", JSONObject.parseObject(sysForm.getFormContent()));*/
}
return map;
}
/**
* 取消申请
* 目前实现方式: 直接将当前流程变更为已完成
*
* @param flowTaskVo
* @return
*/
@Override
public Boolean stopProcess(FlowTaskVo flowTaskVo) {
List<Task> task = taskService.createTaskQuery().processInstanceId(flowTaskVo.getInstanceId()).list();
if (CollectionUtils.isEmpty(task)) {
throw new BusinessException("流程未启动或已执行完成,取消申请失败");
}
// 获取当前流程实例
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(flowTaskVo.getInstanceId())
.singleResult();
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
if (Objects.nonNull(bpmnModel)) {
Process process = bpmnModel.getMainProcess();
List<EndEvent> endNodes = process.findFlowElementsOfType(EndEvent.class, false);
if (CollectionUtils.isNotEmpty(endNodes)) {
// TODO 取消流程为什么要设置流程发起人?
// SysUser loginUser = SecurityUtils.getLoginUser().getUser();
// Authentication.setAuthenticatedUserId(loginUser.getUserId().toString());
// taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.STOP.getType(),
// StringUtils.isBlank(flowTaskVo.getComment()) ? "取消申请" : flowTaskVo.getComment());
// 获取当前流程最后一个节点
String endId = endNodes.get(0).getId();
List<Execution> executions = runtimeService.createExecutionQuery()
.parentId(processInstance.getProcessInstanceId()).list();
List<String> executionIds = new ArrayList<>();
executions.forEach(execution -> executionIds.add(execution.getId()));
// 变更流程为已结束状态
runtimeService.createChangeActivityStateBuilder()
.moveExecutionsToSingleActivityId(executionIds, endId).changeState();
}
}
return true;
}
/**
* 驳回任务
*
* @param flowTaskVo
*/
@Override
public void taskReject(FlowTaskVo flowTaskVo) {
if (taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult().isSuspended()) {
throw new BusinessException("任务处于挂起状态!");
}
// 当前任务 task
Task task = taskService.createTaskQuery().taskId(flowTaskVo.getTaskId()).singleResult();
// 获取流程定义信息
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
// 获取所有节点信息
Process process = repositoryService.getBpmnModel(processDefinition.getId()).getProcesses().get(0);
// 获取全部节点列表,包含子节点
Collection<FlowElement> allElements = FlowableUtils.getAllElements(process.getFlowElements(), null);
// 获取当前任务节点元素
FlowElement source = null;
if (allElements != null) {
for (FlowElement flowElement : allElements) {
// 类型为用户节点
if (flowElement.getId().equals(task.getTaskDefinitionKey())) {
// 获取节点信息
source = flowElement;
}
}
}
// 目的获取所有跳转到的节点 targetIds
// 获取当前节点的所有父级用户任务节点
// 深度优先算法思想:延边迭代深入
List<UserTask> parentUserTaskList = FlowableUtils.iteratorFindParentUserTasks(source, null, null);
if (parentUserTaskList == null || parentUserTaskList.size() == 0) {
throw new BusinessException("当前节点为初始任务节点,不能驳回");
}
// 获取活动 ID 即节点 Key
List<String> parentUserTaskKeyList = new ArrayList<>();
parentUserTaskList.forEach(item -> parentUserTaskKeyList.add(item.getId()));
// 获取全部历史节点活动实例,即已经走过的节点历史,数据采用开始时间升序
List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId()).orderByHistoricTaskInstanceStartTime().asc().list();
// 数据清洗,将回滚导致的脏数据清洗掉
List<String> lastHistoricTaskInstanceList = FlowableUtils.historicTaskInstanceClean(allElements, historicTaskInstanceList);
// 此时历史任务实例为倒序,获取最后走的节点
List<String> targetIds = new ArrayList<>();
// 循环结束标识,遇到当前目标节点的次数
int number = 0;
StringBuilder parentHistoricTaskKey = new StringBuilder();
for (String historicTaskInstanceKey : lastHistoricTaskInstanceList) {
// 当会签时候会出现特殊的,连续都是同一个节点历史数据的情况,这种时候跳过
if (parentHistoricTaskKey.toString().equals(historicTaskInstanceKey)) {
continue;
}
parentHistoricTaskKey = new StringBuilder(historicTaskInstanceKey);
if (historicTaskInstanceKey.equals(task.getTaskDefinitionKey())) {
number++;
}
// 在数据清洗后,历史节点就是唯一一条从起始到当前节点的历史记录,理论上每个点只会出现一次
// 在流程中如果出现循环,那么每次循环中间的点也只会出现一次,再出现就是下次循环
// number == 1第一次遇到当前节点
// number == 2第二次遇到代表最后一次的循环范围
if (number == 2) {
break;
}
// 如果当前历史节点,属于父级的节点,说明最后一次经过了这个点,需要退回这个点
if (parentUserTaskKeyList.contains(historicTaskInstanceKey)) {
targetIds.add(historicTaskInstanceKey);
}
}
// 目的获取所有需要被跳转的节点 currentIds
// 取其中一个父级任务,因为后续要么存在公共网关,要么就是串行公共线路
UserTask oneUserTask = parentUserTaskList.get(0);
// 获取所有正常进行的任务节点 Key这些任务不能直接使用需要找出其中需要撤回的任务
List<Task> runTaskList = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).list();
List<String> runTaskKeyList = new ArrayList<>();
runTaskList.forEach(item -> runTaskKeyList.add(item.getTaskDefinitionKey()));
// 需驳回任务列表
List<String> currentIds = new ArrayList<>();
// 通过父级网关的出口连线,结合 runTaskList 比对,获取需要撤回的任务
List<UserTask> currentUserTaskList = FlowableUtils.iteratorFindChildUserTasks(oneUserTask, runTaskKeyList, null, null);
currentUserTaskList.forEach(item -> currentIds.add(item.getId()));
// 规定:并行网关之前节点必须需存在唯一用户任务节点,如果出现多个任务节点,则并行网关节点默认为结束节点,原因为不考虑多对多情况
if (targetIds.size() > 1 && currentIds.size() > 1) {
throw new BusinessException("任务出现多对多情况,无法撤回");
}
// 循环获取那些需要被撤回的节点的ID用来设置驳回原因
List<String> currentTaskIds = new ArrayList<>();
currentIds.forEach(currentId -> runTaskList.forEach(runTask -> {
if (currentId.equals(runTask.getTaskDefinitionKey())) {
currentTaskIds.add(runTask.getId());
}
}));
// 设置驳回意见
currentTaskIds.forEach(item -> taskService.addComment(item, task.getProcessInstanceId(), FlowComment.REJECT.getType(), flowTaskVo.getComment()));
try {
// 如果父级任务多于 1 个,说明当前节点不是并行节点,原因为不考虑多对多情况
if (targetIds.size() > 1) {
// 1 对 多任务跳转currentIds 当前节点(1)targetIds 跳转到的节点(多)
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(task.getProcessInstanceId()).
moveSingleActivityIdToActivityIds(currentIds.get(0), targetIds).changeState();
}
// 如果父级任务只有一个,因此当前任务可能为网关中的任务
if (targetIds.size() == 1) {
// 1 对 1 或 多 对 1 情况currentIds 当前要跳转的节点列表(1或多)targetIds.get(0) 跳转到的节点(1)
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(task.getProcessInstanceId())
.moveActivityIdsToSingleActivityId(currentIds, targetIds.get(0)).changeState();
}
} catch (FlowableObjectNotFoundException e) {
throw new BusinessException("未找到流程实例,流程可能已发生变化");
} catch (FlowableException e) {
throw new BusinessException("无法取消或开始活动");
}
}
/**
* 流程完成时间处理
*
* @param ms
* @return
*/
private String getDate(long ms) {
long day = ms / (24 * 60 * 60 * 1000);
long hour = (ms / (60 * 60 * 1000) - day * 24);
long minute = ((ms / (60 * 1000)) - day * 24 * 60 - hour * 60);
long second = (ms / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60);
if (day > 0) {
return day + "" + hour + "小时" + minute + "分钟";
}
if (hour > 0) {
return hour + "小时" + minute + "分钟";
}
if (minute > 0) {
return minute + "分钟";
}
if (second > 0) {
return second + "";
} else {
return 0 + "";
}
}
}