public interface ProApprovalFlowAppService {
/**
* 提交
*
* @param submitDto submitDto
* @return ResultDto
*/
ResultDto<ProApprovalFlowInstanceDto> submit(SubmitDto submitDto);
/**
* 异步提交
*
* @param submitDto submitDto
* @return ResultDto
*/
ResultDto<String> submitAsync(SubmitDto submitDto);
/**
* 撤回
*
* @param approvalDto approvalDto
* @return ResultDto
*/
ResultDto<String> revoke(ApprovalDto approvalDto);
/**
* 同意
*
* @param approvalDto approvalDto
* @return ResultDto
*/
ResultDto<String> agree(ApprovalDto approvalDto);
/**
* 驳回
*
* @param approvalDto approvalDto
* @return ResultDto
*/
ResultDto<String> reject(ApprovalDto approvalDto);
/**
* 转审
*
* @param approvalDto approvalDto
* @return ResultDto
*/
ResultDto<String> referral(ApprovalDto approvalDto);
/**
* 作废
*
* @param approvalDto approvalDto
* @return ResultDto
*/
ResultDto<String> abort(ApprovalDto approvalDto);
/**
* 删除
*
* @param bizType bizType
* @param bizDataId bizDataId
* @return ResultDto
*/
ResultDto<String> delete(String bizType, String bizDataId);
/**
* 清空日志
*
* @param bizType bizType
* @param bizDataId bizDataId
* @return ResultDto
*/
ResultDto<String> clearLog(String bizType, String bizDataId);
/**
* 修改Owner
*
* @param modifyOwnerDto modifyOwnerDto
* @return ResultDto
*/
ResultDto<String> modifyOwner(ModifyOwnerDto modifyOwnerDto);
/**
* 获取流程实例的基本信息
*
* @param bizType bizType
* @param bizDataId bizDataId
* @return ResultDto
*/
ResultDto<ProApprovalFlowInstanceDto> getInstanceInfo(String bizType, String bizDataId);
/**
* 保存日志
*
* @param logDto logDto
* @return ResultDto
*/
ResultDto<String> saveLog(ApprovalLogDto logDto);
/**
* 异步保存日志
*
* @param logDto logDto
* @return ResultDto
*/
ResultDto<String> saveLogAsync(ApprovalLogDto logDto);
/**
* 获取审批日志
*
* @param bizType bizType
* @param bizDataId bizDataId
* @return ResultDto
*/
ResultDto<List<ProApprovalFlowLogDto>> getLog(String bizType, String bizDataId);
/**
* 审批系统节点
*
* @param approveSysNodeDto approveSysNodeDto
* @return ResultDto
*/
ResultDto<String> approveSysNode(ApproveSysNodeDto approveSysNodeDto);
/**
* 获取审批人
*
* @param bizType bizType
* @param bizDataId bizDataId
* @return ResultDto
*/
ResultDto<List<NodeApproverDto>> getApprover(String bizType, String bizDataId);
/**
* 获取流程节点
*
* @param bizType bizType
* @param bizDataId bizDataId
* @return ResultDto
*/
ResultDto<List<FlowNodeDto>> getFlow(String bizType, String bizDataId);
/**
* 重新启动
*
* @param restartDto restartDto
* @return ResultDto
*/
ResultDto<String> restart(RestartDto restartDto);
}
@Service
@Slf4j
public class ProApprovalFlowAppServiceImpl implements ProApprovalFlowAppService {
private static final String COMMON_LOG_MSG = "bizType : {},bizDataId : {}";
@Autowired
private ProApprovalFlowInstanceDomainService instanceService;
@Autowired
private ProApprovalFlowNodeDomainService nodeService;
@Autowired
private ProApprovalFlowNodeHandlerDomainService nodeHandlerService;
@Autowired
private ProApprovalFlowDomainService flowService;
@Autowired
private ProApprovalFlowTodoDomainService toDoService;
@Autowired
private ProApprovalFlowLogDomainService logService;
@Autowired
private ApplicationContext context;
@Autowired
private ApprovalEventPublisher eventPublisher;
@Autowired
private TodoWeLinkService todoWelinkService;
@Autowired
private ApprovalSubmitUtil approvalSubmitUtil;
@Autowired
private ApprovalAgreeUtil approvalAgreeUtil;
@Autowired
private ApprovalRejectUtil approvalRejectUtil;
@Override
public ResultDto<ProApprovalFlowInstanceDto> submit(SubmitDto submitDto) {
CommonUtil.setContext(submitDto.getW3account(), submitDto.getUserCn());
log.info("ApprovalFlow submit : {}", JSON.toJSONString(submitDto));
Long flowId = submitDto.getFlowId();
String logRemark = "用户提交";
String opType = ApprovalEnum.SUBMIT.name();
// 参数校验
CommonUtil.validate(submitDto);
// 查询流程实例
ProApprovalFlowInstanceDto instance =
instanceService.loadByBizTypeBizDataId(submitDto.getBizType(), submitDto.getBizDataId());
if (instance.getFlowInstanceId() != null) {
// 处理待办
ResultDto resultDto = completeRejectTodo(instance);
if (resultDto.getCode() != SUCCESS_CODE) {
return resultDto;
}
// 删除该实例下的所有节点处理人
logRemark = "用户重新提交";
opType = ApprovalEnum.RESUBMIT.name();
nodeHandlerService.deleteByInstanceId(instance.getFlowInstanceId());
}
// 保存流程实例
ProApprovalFlowInstanceDto instanceDto = approvalSubmitUtil.saveInstance(submitDto, instance);
// 保存节点处理人
approvalSubmitUtil.saveNodeHandler(instanceDto, submitDto);
// 激活节点
String flowNodeVersion = instanceDto.getFlowNodeVersion();
ProApprovalFlowNodeDto nextNode = new ProApprovalFlowNodeDto();
if (instance.getFlowInstanceId() != null && instance.getResubmitNode() != null) {
nextNode = nodeService.load(instance.getResubmitNode());
instanceService.modifyResubmitNode(instance.getFlowInstanceId(), null);
}
if (nextNode.getFlowNodeId() == null) {
nextNode = nodeService.loadByFlowIdAndVersion(flowId, flowNodeVersion, SORT_NUM_2);
}
ProApprovalFlowNodeDto curNode;
if (instance.getFlowInstanceId() == null) {
curNode = nodeService.loadByFlowIdAndVersion(flowId, flowNodeVersion, SORT_NUM_1);
} else {
curNode = nodeService.load(instance.getCurrentNode());
}
instanceDto.setCurrentNode(curNode.getFlowNodeId());
logRemark = StringUtils.hasText(submitDto.getRemark()) ? submitDto.getRemark() : logRemark;
approvalSubmitUtil.activateNode(instanceDto, nextNode, opType, logRemark);
return new ResultDto<>(getInstanceInfo(submitDto.getBizType(), submitDto.getBizDataId()).getData());
}
private ResultDto completeRejectTodo(ProApprovalFlowInstanceDto instance) {
// 重新提交的前提是实例状态为驳回、撤回、重新启动
if (!ApprovalEnum.REJECT.name().equals(instance.getStatus())
&& !ApprovalEnum.REVOKE.name().equals(instance.getStatus())
&& !ApprovalEnum.RESTART.name().equals(instance.getStatus())) {
return ResultDto.fail(ApprovalErrorEnum.ILLEGAL_INSTANCE_STATUS);
}
// 驳回、重新启动完成待办
UserVO user = CommonUtil.getCurrentUser();
if (ApprovalEnum.REJECT.name().equals(instance.getStatus())
|| ApprovalEnum.RESTART.name().equals(instance.getStatus())) {
Optional<ProApprovalFlowTodoDto> todoOpt = toDoService.loadByHandler(instance.getFlowInstanceId(),
instance.getCurrentNode(), user.getUserAccount());
if (ApprovalEnum.REJECT.name().equals(instance.getStatus()) && !todoOpt.isPresent()) {
return ResultDto.fail(ApprovalErrorEnum.NO_AUTH);
}
if (todoOpt.isPresent()) {
ProApprovalFlowTodoDto todoDto = todoOpt.get();
todoWelinkService.completeToDoAsync(new TodoCompleteDto(todoDto.getAppTaskId(), todoDto.getHandler()));
todoDto.setResult(ApprovalEnum.AGREE.name());
todoDto.setActiveFlag(NO);
toDoService.modify(todoDto);
}
}
return new ResultDto();
}
@Override
public ResultDto<String> submitAsync(SubmitDto submitDto) {
ApprovalTask.submit(submitDto);
return new ResultDto<>();
}
@Override
public ResultDto<String> revoke(ApprovalDto approvalDto) {
CommonUtil.setContext(approvalDto.getW3account(), approvalDto.getUserCn());
log.info("ApprovalFlow revoke start: {}", JSON.toJSONString(approvalDto));
TimerUtil timerAll = new TimerUtil();
// 参数校验
CommonUtil.validate(approvalDto);
String bizType = approvalDto.getBizType();
String bizDataId = approvalDto.getBizDataId();
UserVO user = CommonUtil.getCurrentUser();
// 权限校验
ProApprovalFlowInstanceDto instance = instanceService.loadByBizTypeBizDataId(bizType, bizDataId);
if (instance.getFlowInstanceId() == null || !instance.getOwner().equals(user.getUserAccount())
|| !instance.getStatus().equals(ApprovalEnum.RUNNING.name())) {
return ResultDto.fail(ApprovalErrorEnum.NO_AUTH_REVOKE);
}
// 完成当前实例的所有待办
Long flowInstanceId = instance.getFlowInstanceId();
Long currentNode = instance.getCurrentNode();
List<ProApprovalFlowTodoDto> todoList = toDoService.loadByInstance(flowInstanceId);
for (ProApprovalFlowTodoDto todoDto : todoList) {
if (todoDto.getResult().equals(ApprovalEnum.UNHANDLED.name())) {
todoWelinkService.completeToDoAsync(new TodoCompleteDto(todoDto.getAppTaskId(), todoDto.getHandler()));
todoDto.setResult(ApprovalEnum.REVOKE.name());
}
}
// 把当前实例所有待办的激活状态改为未激活,待办结果置为撤回
toDoService.invalid(todoList);
// 实例状态置为撤回
instanceService.modifyStatus(flowInstanceId, ApprovalEnum.REVOKE.name());
// 激活第一个流程节点
ProApprovalFlowNodeDto nextNode =
nodeService.loadByFlowIdAndVersion(instance.getFlowId(), instance.getFlowNodeVersion(), SORT_NUM_1);
instanceService.updateCurNode(flowInstanceId, nextNode.getFlowNodeId());
instance.setCurrentNode(nextNode.getFlowNodeId());
instance.setCurrentNodeCode(nextNode.getFlowNodeCode());
instance.setCurrentNodeName(nextNode.getFlowNodeName());
// 触发流程撤回事件
RevokeEvent revokeEvent = new RevokeEvent(instance);
eventPublisher.publishEvent(revokeEvent);
// 保存撤回日志
logService.save(flowInstanceId, currentNode, ApprovalEnum.REVOKE.name(), "用户主动撤回");
timerAll.print("==========revoke end");
return new ResultDto<>();
}
@Override
public ResultDto<String> agree(ApprovalDto approvalDto) {
CommonUtil.setContext(approvalDto.getW3account(), approvalDto.getUserCn());
log.info("ApprovalFlow agree start: {}", JSON.toJSONString(approvalDto));
// 参数校验
CommonUtil.validate(approvalDto);
// 权限校验
ResultDto checkAuthResult = approvalAgreeUtil.checkAuth(approvalDto.getBizType(), approvalDto.getBizDataId());
if (checkAuthResult.getCode() != SUCCESS_CODE) {
return checkAuthResult;
}
ProApprovalFlowInstanceDto instance = (ProApprovalFlowInstanceDto) checkAuthResult.getResult();
// 完成自己的待办
ProApprovalFlowTodoDto todoDto = (ProApprovalFlowTodoDto) checkAuthResult.getData();
todoWelinkService.completeToDoAsync(new TodoCompleteDto(todoDto.getAppTaskId(), todoDto.getHandler()));
// 将自己的待办结果置为同意,保存审批意见
todoDto.setResult(ApprovalEnum.AGREE.name());
todoDto.setComment(approvalDto.getComment());
toDoService.modify(todoDto);
// 激活下一个流程节点,如果已经是最后一个节点,则触发流程已完成事件
ProApprovalFlowNodeDto curNode = nodeService.load(instance.getCurrentNode());
boolean isNodeFinishedFlag = approvalAgreeUtil.isFinished(instance, curNode);
log.info("isNodeFinishedFlag: {}", isNodeFinishedFlag);
Long flowInstanceId = instance.getFlowInstanceId();
ResultDto<String> resultDto = new ResultDto<>();
if (isNodeFinishedFlag) {
// 节点完成,需完成其他未处理人的待办
approvalRejectUtil.cancelOtherTodo(flowInstanceId);
if (YES.equals(curNode.getLastFlag())) {
approvalSubmitUtil.processLastNode(instance, curNode, todoDto);
return resultDto;
}
// 激活下一个流程节点
ProApprovalFlowNodeDto nextNode = nodeService.loadByFlowIdAndVersion(instance.getFlowId(), instance.getFlowNodeVersion(),
curNode.getSortNum() + 1);
approvalSubmitUtil.activateNode(instance, nextNode, ApprovalEnum.AGREE.name(), approvalDto.getComment());
return resultDto;
}
// 保存同意日志
logService.save(flowInstanceId, curNode.getFlowNodeId(), ApprovalEnum.AGREE.name(),
approvalDto.getComment());
return resultDto;
}
private void finishLastNode(ProApprovalFlowInstanceDto instance, ProApprovalFlowTodoDto todoDto) {
// 如果是最后节点则更新实例状态为已完成
instanceService.modifyStatus(instance.getFlowInstanceId(), ApprovalEnum.FINISHED.name());
ProApprovalFlowDto flowDto = flowService.load(instance.getFlowId());
instance.setBizStatus(flowDto.getBizFinishedStatus());
// 给责任人发已完成WeLink通知
TodoDto todo = ApprovalSubmitUtil.getTodo(instance.getBizData(), flowDto.getTodoDoneRule());
approvalSubmitUtil.sendWeLinkNotice(todo.getTitle(), todo.getDesc(), instance.getOwner(), todo.getUrl());
// 最后一个节点将待办失效
todoDto.setActiveFlag(NO);
toDoService.modify(todoDto);
}
@Override
public ResultDto<String> reject(ApprovalDto approvalDto) {
CommonUtil.setContext(approvalDto.getW3account(), approvalDto.getUserCn());
log.info("ApprovalFlow reject start: {}", JSON.toJSONString(approvalDto));
TimerUtil timerAll = new TimerUtil();
// 参数校验
CommonUtil.validate(approvalDto);
Assert.hasText(approvalDto.getComment(), "reject comment is required");
String bizType = approvalDto.getBizType();
String bizDataId = approvalDto.getBizDataId();
// 权限校验
ResultDto checkAuthResult = approvalAgreeUtil.checkAuth(bizType, bizDataId);
if (checkAuthResult.getCode() != SUCCESS_CODE) {
return checkAuthResult;
}
ProApprovalFlowInstanceDto instance = (ProApprovalFlowInstanceDto) checkAuthResult.getResult();
ProApprovalFlowNodeDto curNode = nodeService.load(instance.getCurrentNode());
// 完成自己的待办
ProApprovalFlowTodoDto todoDto = (ProApprovalFlowTodoDto) checkAuthResult.getData();
todoWelinkService.completeToDoAsync(new TodoCompleteDto(todoDto.getAppTaskId(), todoDto.getHandler()));
// 将自己的待办结果置为驳回,保存审批意见
todoDto.setResult(ApprovalEnum.REJECT.name());
todoDto.setComment(approvalDto.getComment());
toDoService.modify(todoDto);
// 判断是否驳回
boolean isRejectFlag = approvalRejectUtil.isReject(instance, curNode);
log.info("isRejectFlag : {}", isRejectFlag);
if (isRejectFlag) {
// 完成当前实例的所有待办,待办结果置为取消
Long flowInstanceId = instance.getFlowInstanceId();
approvalRejectUtil.cancelOtherTodo(flowInstanceId);
// 实例状态置为驳回
instanceService.modifyStatus(flowInstanceId, ApprovalEnum.REJECT.name());
// 激活驳回节点
Long rejectNodeId = approvalRejectUtil.getRejectNode(instance.getBizData(), curNode.getRejectNodeRule());
ProApprovalFlowNodeDto rejectNode = nodeService.load(rejectNodeId);
approvalSubmitUtil.activateNode(instance, rejectNode, ApprovalEnum.REJECT.name(), approvalDto.getComment());
// 保存重新提交节点
if (approvalRejectUtil.getResubmitToSelf(instance.getBizData(), curNode.getResubmitToSelf())) {
instanceService.modifyResubmitNode(instance.getFlowInstanceId(), curNode.getFlowNodeId());
}
}
timerAll.print("==========reject end");
return new ResultDto<>();
}
@Override
public ResultDto<String> referral(ApprovalDto approvalDto) {
CommonUtil.setContext(approvalDto.getW3account(), approvalDto.getUserCn());
log.info("ApprovalFlow referral start: {}", JSON.toJSONString(approvalDto));
TimerUtil timerAll = new TimerUtil();
// 参数校验
CommonUtil.validate(approvalDto);
// 权限校验
ResultDto checkAuthResult = approvalAgreeUtil.checkAuthReferral(approvalDto);
if (checkAuthResult.getCode() != SUCCESS_CODE) {
return checkAuthResult;
}
ProApprovalFlowInstanceDto instance = (ProApprovalFlowInstanceDto) checkAuthResult.getResult();
// 完成自己的待办
ProApprovalFlowTodoDto todoDto = (ProApprovalFlowTodoDto) checkAuthResult.getData();
todoWelinkService.completeToDoAsync(new TodoCompleteDto(todoDto.getAppTaskId(), todoDto.getHandler()));
// 将自己的待办结果置为转审,保存转审意见
UserVO user = CommonUtil.getCurrentUser();
todoDto.setResult(ApprovalEnum.REFERRAL.name());
todoDto.setForwardUser(user.getUserAccount());
todoDto.setForwardUserName(user.getUserCN());
todoDto.setComment(todoDto.getHandler() + " forward to " + approvalDto.getForwardUser());
toDoService.modify(todoDto);
// 给转后审批人发待办
ProApprovalFlowNodeHandlerDto handlerDto = new ProApprovalFlowNodeHandlerDto();
handlerDto.setHandler(approvalDto.getForwardUser());
handlerDto.setHandlerName(approvalDto.getForwardUserName());
ProApprovalFlowNodeDto curNode = nodeService.load(instance.getCurrentNode());
TodoDto todo = ApprovalSubmitUtil.getTodo(instance.getBizData(), curNode.getActiveTodoRule());
ApprovalDto approval = new ApprovalDto();
approval.setForwardUser(user.getUserAccount());
approval.setForwardUserName(user.getUserCN());
approvalSubmitUtil.approvalSendTodo(instance, handlerDto, todo, approval);
log.info("approvalSubmitUtil.approvalSendTodo");
// 更新审批人表
nodeHandlerService.referral(instance, todoDto.getHandler(), approvalDto.getForwardUser(),
approvalDto.getForwardUserName());
// 发布转审事件
ReferralEvent referralEvent = new ReferralEvent(instance);
referralEvent.setForwardUser(approvalDto.getForwardUser());
referralEvent.setForwardUserName(approvalDto.getForwardUserName());
eventPublisher.publishEvent(referralEvent);
// 保存转审日志
logService.save(instance.getFlowInstanceId(), instance.getCurrentNode(), ApprovalEnum.REFERRAL.name(),
approvalDto.getComment());
timerAll.print("==========referral end");
return new ResultDto<>();
}
@Override
public ResultDto<String> abort(ApprovalDto approvalDto) {
CommonUtil.setContext(approvalDto.getW3account(), approvalDto.getUserCn());
log.info("ApprovalFlow abort start: {}", JSON.toJSONString(approvalDto));
TimerUtil timerAll = new TimerUtil();
// 参数校验
CommonUtil.validate(approvalDto);
String bizType = approvalDto.getBizType();
String bizDataId = approvalDto.getBizDataId();
// 权限校验
ProApprovalFlowInstanceDto instance = instanceService.loadByBizTypeBizDataId(bizType, bizDataId);
if (instance.getFlowInstanceId() == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
if (instance.getStatus().equals(ApprovalEnum.ABORT.name())) {
return ResultDto.fail(ApprovalErrorEnum.ILLEGAL_INSTANCE_STATUS);
}
// 完成当前实例的所有待办
Long flowInstanceId = instance.getFlowInstanceId();
log.info("flowInstanceId: {}", flowInstanceId);
List<ProApprovalFlowTodoDto> todoList = toDoService.loadByInstance(flowInstanceId);
for (ProApprovalFlowTodoDto todoDto : todoList) {
if (todoDto.getResult().equals(ApprovalEnum.UNHANDLED.name())) {
todoWelinkService.completeToDoAsync(new TodoCompleteDto(todoDto.getAppTaskId(), todoDto.getHandler()));
todoDto.setResult(ApprovalEnum.ABORT.name());
}
}
// 把当前实例所有待办的激活状态改为未激活,待办结果置为作废
toDoService.invalid(todoList);
// 实例状态置为作废
instanceService.modifyStatus(flowInstanceId, ApprovalEnum.ABORT.name());
// 保存作废日志
logService.save(instance.getFlowInstanceId(), instance.getCurrentNode(), ApprovalEnum.ABORT.name(), "已作废");
timerAll.print("==========abort end");
return new ResultDto<>();
}
@Override
public ResultDto<String> delete(String bizType, String bizDataId) {
ProApprovalFlowInstanceDto instanceDto = getInstance(bizType, bizDataId);
if (instanceDto == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
Long flowInstanceId = instanceDto.getFlowInstanceId();
log.info("flowInstanceId : {}", flowInstanceId);
// 完成当前实例的所有待办
List<ProApprovalFlowTodoDto> todoList = toDoService.loadByInstance(flowInstanceId);
for (ProApprovalFlowTodoDto todoDto : todoList) {
if (todoDto.getResult().equals(ApprovalEnum.UNHANDLED.name())) {
todoWelinkService.completeToDoAsync(new TodoCompleteDto(todoDto.getAppTaskId(), todoDto.getHandler()));
}
}
// 删除数据
instanceService.delete(flowInstanceId);
nodeHandlerService.deleteByInstanceId(flowInstanceId);
toDoService.delete(flowInstanceId);
logService.delete(flowInstanceId);
log.info("delete end : {}", flowInstanceId);
return new ResultDto<>();
}
@Override
public ResultDto<String> clearLog(String bizType, String bizDataId) {
ProApprovalFlowInstanceDto instanceDto = getInstance(bizType, bizDataId);
if (instanceDto == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
Long flowInstanceId = instanceDto.getFlowInstanceId();
log.info("flowInstanceId : {}", flowInstanceId);
logService.delete(flowInstanceId);
return new ResultDto<>();
}
@Override
public ResultDto<String> modifyOwner(ModifyOwnerDto modifyOwnerDto) {
CommonUtil.setContext(modifyOwnerDto.getW3account(), modifyOwnerDto.getUserCn());
log.info("modifyOwnerDto : {}", JSON.toJSONString(modifyOwnerDto));
ProApprovalFlowInstanceDto instance = getInstance(modifyOwnerDto.getBizType(), modifyOwnerDto.getBizDataId());
if (instance == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
// 修改实例owner
Long flowInstanceId = instance.getFlowInstanceId();
modifyOwnerDto.setFlowInstanceId(flowInstanceId);
instanceService.modifyOwner(modifyOwnerDto);
// 修改审批人
ProApprovalFlowNodeDto nodeDto =
nodeService.loadByFlowIdAndVersion(instance.getFlowId(), instance.getFlowNodeVersion(), SORT_NUM_1);
nodeHandlerService.deleteNodeHandler(flowInstanceId, nodeDto.getFlowNodeId());
ProApprovalFlowNodeHandlerEntity handlerEntity = new ProApprovalFlowNodeHandlerEntity();
handlerEntity.setFlowInstanceId(flowInstanceId);
handlerEntity.setFlowNodeId(nodeDto.getFlowNodeId());
handlerEntity.setHandler(modifyOwnerDto.getOwner());
handlerEntity.setHandlerName(modifyOwnerDto.getOwnerName());
handlerEntity.setHandlerType(HandlerTypeEnum.APPROVER.name());
CommonUtil.setUser(handlerEntity);
nodeHandlerService.save(handlerEntity);
// 处理驳回待办
if (ApprovalEnum.REJECT.name().equals(instance.getStatus())) {
UserVO user = CommonUtil.getCurrentUser();
Optional<ProApprovalFlowTodoDto> todoOpt = toDoService.loadByHandler(instance.getFlowInstanceId(),
instance.getCurrentNode(), user.getUserAccount());
if (todoOpt.isPresent()) {
// 完成自己的待办
ProApprovalFlowTodoDto todoDto = todoOpt.get();
todoDto.setComment(todoDto.getHandler() + " modifyOwner to " + modifyOwnerDto.getOwner());
completeSelfTodo(todoDto, user);
// 给转后owner发待办
ProApprovalFlowNodeHandlerDto handlerDto = new ProApprovalFlowNodeHandlerDto();
handlerDto.setHandler(modifyOwnerDto.getOwner());
handlerDto.setHandlerName(modifyOwnerDto.getOwnerName());
List<ProApprovalFlowLogDto> logs = logService.loadByFlowInstanceId(instance.getFlowInstanceId());
ProApprovalFlowLogDto maxLog = logs.stream()
.filter(item -> ApprovalEnum.REJECT.name().equals(item.getOpType()))
.max(Comparator.comparing(ProApprovalFlowLogDto::getCreateDate))
.get();
ProApprovalFlowNodeDto rejectNode = nodeService.load(maxLog.getFlowNodeId());
TodoDto todo = ApprovalSubmitUtil.getTodo(instance.getBizData(), rejectNode.getRejectTodoRule());
ApprovalDto approval = new ApprovalDto();
approval.setForwardUser(user.getUserAccount());
approval.setForwardUserName(user.getUserCN());
approvalSubmitUtil.approvalSendTodo(instance, handlerDto, todo, approval);
}
}
return new ResultDto<>();
}
private void completeSelfTodo(ProApprovalFlowTodoDto todoDto, UserVO user) {
todoWelinkService.completeToDoAsync(new TodoCompleteDto(todoDto.getAppTaskId(), todoDto.getHandler()));
todoDto.setResult(ApprovalEnum.MODIFY_OWNER.name());
todoDto.setForwardUser(user.getUserAccount());
todoDto.setForwardUserName(user.getUserCN());
toDoService.modify(todoDto);
}
@Override
public ResultDto<String> saveLog(ApprovalLogDto logDto) {
CommonUtil.setContext(logDto.getW3account(), logDto.getUserCn());
log.info("ApprovalFlow saveLog : {}", JSON.toJSONString(logDto));
String bizType = logDto.getBizType();
String bizDataId = logDto.getBizDataId();
ProApprovalFlowInstanceDto instanceDto = getInstance(bizType, bizDataId);
if (instanceDto == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
Long flowNodeId = instanceDto.getCurrentNode();
if (StringUtils.hasText(logDto.getFlowNodeCode())) {
ProApprovalFlowNodeDto nodeDto = nodeService.loadByFlowCodeAndVersion(instanceDto.getFlowId(),
logDto.getFlowNodeCode(), instanceDto.getFlowNodeVersion());
flowNodeId = nodeDto.getFlowNodeId();
}
logService.save(instanceDto.getFlowInstanceId(), flowNodeId, logDto.getOpType(), logDto.getRemark());
return new ResultDto<>();
}
@Override
public ResultDto<String> saveLogAsync(ApprovalLogDto logDto) {
ApprovalTask.submit(logDto);
return new ResultDto<>();
}
@Override
public ResultDto<ProApprovalFlowInstanceDto> getInstanceInfo(String bizType, String bizDataId) {
ProApprovalFlowInstanceDto instanceDto = getInstance(bizType, bizDataId);
if (instanceDto == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
return new ResultDto<>(instanceDto);
}
@Override
public ResultDto<List<ProApprovalFlowLogDto>> getLog(String bizType, String bizDataId) {
ProApprovalFlowInstanceDto instanceDto = getInstance(bizType, bizDataId);
if (instanceDto == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
return new ResultDto<>(logService.loadByFlowInstanceId(instanceDto.getFlowInstanceId()));
}
@Override
public ResultDto<String> approveSysNode(ApproveSysNodeDto approvalDto) {
log.info("approvalDto : {}", JSON.toJSONString(approvalDto));
CommonUtil.setContext();
Long flowInstanceId = approvalDto.getFlowInstanceId();
String flowNodeCode = approvalDto.getFlowNodeCode();
ProApprovalFlowInstanceDto instance = instanceService.load(flowInstanceId);
if (instance.getFlowInstanceId() == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
ProApprovalFlowNodeDto curNode = nodeService.load(instance.getCurrentNode());
if (!flowNodeCode.equals(curNode.getFlowNodeCode())) {
return ResultDto.fail(ApprovalErrorEnum.CURRENT_NODE_ERROR);
}
boolean isAgree = AGREE.equals(approvalDto.getResult());
ResultDto<String> resultDto = new ResultDto<>();
ProApprovalFlowNodeDto nextNode;
if (isAgree) {
if (YES.equals(curNode.getLastFlag())) {
approvalSubmitUtil.processLastNode(instance, curNode, null);
return resultDto;
}
// 激活下一个流程节点
nextNode = nodeService.loadByFlowIdAndVersion(instance.getFlowId(), instance.getFlowNodeVersion(),
curNode.getSortNum() + 1);
approvalSubmitUtil.activateNode(instance, nextNode, ApprovalEnum.AGREE.name(), approvalDto.getComment());
return resultDto;
}
// 获取驳回节点
Long rejectNodeId = approvalRejectUtil.getRejectNode(instance.getBizData(), curNode.getRejectNodeRule());
nextNode = nodeService.load(rejectNodeId);
// 实例状态置为驳回
instanceService.modifyStatus(flowInstanceId, ApprovalEnum.REJECT.name());
// 激活节点
approvalSubmitUtil.activateNode(instance, nextNode, ApprovalEnum.REJECT.name(), approvalDto.getComment());
return new ResultDto<>();
}
@Override
public ResultDto<List<NodeApproverDto>> getApprover(String bizType, String bizDataId) {
ProApprovalFlowInstanceDto instanceDto = getInstance(bizType, bizDataId);
if (instanceDto == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
List<ProApprovalFlowNodeHandlerDto> list = nodeHandlerService.loadByInstance(instanceDto.getFlowInstanceId());
List<NodeApproverDto> result = new ArrayList<>();
list.forEach(item -> {
NodeApproverDto dto = new NodeApproverDto();
BeanUtils.copyProperties(item, dto);
result.add(dto);
});
return new ResultDto<>(result);
}
@Override
public ResultDto<List<FlowNodeDto>> getFlow(String bizType, String bizDataId) {
ProApprovalFlowInstanceDto instanceDto = getInstance(bizType, bizDataId);
if (instanceDto == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
List<FlowNodeDto> resultNode = new ArrayList<>();
List<ProApprovalFlowNodeDto> nodeList = nodeService.getByFlowId(instanceDto);
for (ProApprovalFlowNodeDto nodeDto : nodeList) {
FlowNodeDto dto = new FlowNodeDto();
BeanUtils.copyProperties(nodeDto, dto);
resultNode.add(dto);
}
List<FlowNodeDto> list =
resultNode.stream().sorted(Comparator.comparing(FlowNodeDto::getSortNum)).collect(Collectors.toList());
String currentLanguage = RequestContext.getCurrent().getUserLanguage();
if ("en_US".equals(currentLanguage) && !CollectionUtils.isEmpty(list)) {
for (FlowNodeDto flowNodeDto : list) {
flowNodeDto.setFlowNodeNameEn(ApprovalFlowNodeEnum.getNameEn(flowNodeDto.getFlowNodeName()));
}
}
return new ResultDto<>(list);
}
@Override
public ResultDto<String> restart(RestartDto restartDto) {
CommonUtil.setContext(restartDto.getW3account(), restartDto.getUserCn());
String bizType = restartDto.getBizType();
String bizDataId = restartDto.getBizDataId();
ProApprovalFlowInstanceDto instanceDto = getInstance(bizType, bizDataId);
if (instanceDto == null) {
return ResultDto.fail(ApprovalErrorEnum.NOT_FIND_INSTANCE);
}
ProApprovalFlowNodeDto nodeDto = nodeService.loadByFlowCodeAndVersion(instanceDto.getFlowId(),
restartDto.getFlowNodeCode(), instanceDto.getFlowNodeVersion());
instanceService.modifyStatus(instanceDto.getFlowInstanceId(), ApprovalEnum.RESTART.name());
logService.save(instanceDto.getFlowInstanceId(), nodeDto.getFlowNodeId(), ApprovalEnum.RESTART.name(),
restartDto.getRemark());
UserVO user = CommonUtil.getCurrentUser();
Optional<ProApprovalFlowTodoDto> todoOpt = toDoService.loadByHandler(instanceDto.getFlowInstanceId(),
instanceDto.getCurrentNode(), user.getUserAccount());
todoOpt.ifPresent(todoDto -> {
todoWelinkService.completeToDoAsync(new TodoCompleteDto(todoDto.getAppTaskId(), todoDto.getHandler()));
todoDto.setResult(ApprovalEnum.RESTART.name());
todoDto.setForwardUser(user.getUserAccount());
todoDto.setForwardUserName(user.getUserCN());
todoDto.setComment(ApprovalEnum.RESTART.name());
toDoService.modify(todoDto);
});
return new ResultDto<>();
}
private ProApprovalFlowInstanceDto getInstance(String bizType, String bizDataId) {
log.info(COMMON_LOG_MSG, bizType, bizDataId);
ProApprovalFlowInstanceDto instanceInfo = instanceService.getInstanceInfo(bizType, bizDataId);
if (ObjectUtils.isEmpty(instanceInfo.getFlowInstanceId())) {
return null;
}
return instanceInfo;
}
}