bpm 增加流程被通过、不通过时,发送短信通知

This commit is contained in:
YunaiV 2022-01-22 00:35:33 +08:00
parent e3b86b3d7a
commit c2db893fb8
11 changed files with 160 additions and 31 deletions

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.adminserver.modules.bpm.convert.message; package cn.iocoder.yudao.adminserver.modules.bpm.convert.message;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO; import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
import org.activiti.api.task.model.Task; import org.activiti.api.task.model.Task;
@ -36,4 +38,20 @@ public interface BpmMessageConvert {
}) })
void copyTo(Task task, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to); void copyTo(Task task, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);
default BpmMessageSendWhenProcessInstanceRejectReqDTO convert(ProcessInstance processInstance, String comment) {
BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO = new BpmMessageSendWhenProcessInstanceRejectReqDTO();
copyTo(processInstance, reqDTO);
reqDTO.setComment(comment);
return reqDTO;
}
@Mapping(source = "name", target = "processInstanceName")
void copyTo(ProcessInstance from, @MappingTarget BpmMessageSendWhenProcessInstanceRejectReqDTO to);
@Mappings({
@Mapping(source = "id", target = "processInstanceId"),
@Mapping(source = "name", target = "processInstanceName"),
@Mapping(source = "initiator", target = "startUserId")
})
BpmMessageSendWhenProcessInstanceApproveReqDTO convert(org.activiti.api.process.model.ProcessInstance processInstance);
} }

View File

@ -13,6 +13,8 @@ import lombok.Getter;
@Getter @Getter
public enum BpmMessageEnum { public enum BpmMessageEnum {
PROCESS_INSTANCE_APPROVE("bpm_process_instance_approve"), // 流程任务被审批通过时发送给申请人
PROCESS_INSTANCE_REJECT("bpm_process_instance_reject"), // 流程任务被审批不通过时发送给申请人
TASK_ASSIGNED("bpm_task_assigned"); // 任务被分配时发送给审批人 TASK_ASSIGNED("bpm_task_assigned"); // 任务被分配时发送给审批人
/** /**

View File

@ -12,7 +12,7 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum BpmProcessInstanceDeleteReasonEnum { public enum BpmProcessInstanceDeleteReasonEnum {
REJECT_TASK("驳回任务"); REJECT_TASK("不通过任务,原因:{}");
private final String reason; private final String reason;

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.adminserver.modules.bpm.service.message; package cn.iocoder.yudao.adminserver.modules.bpm.service.message;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO; import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
import javax.validation.Valid; import javax.validation.Valid;
@ -13,6 +15,26 @@ import javax.validation.Valid;
*/ */
public interface BpmMessageService { public interface BpmMessageService {
/**
* 发送流程实例被通过的消息
*
* @param reqDTO 发送信息
*/
void sendMessageWhenProcessInstanceApprove(@Valid BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO);
/**
* 发送流程实例被不通过的消息
*
* @param reqDTO 发送信息
*/
void sendMessageWhenProcessInstanceReject(@Valid BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO);
/**
* 发送任务被分配的消息
*
* @param reqDTO 发送信息
*/
void sendMessageWhenTaskAssigned(@Valid BpmMessageSendWhenTaskCreatedReqDTO reqDTO); void sendMessageWhenTaskAssigned(@Valid BpmMessageSendWhenTaskCreatedReqDTO reqDTO);
} }

View File

@ -0,0 +1,27 @@
package cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* BPM 发送流程实例被通过 Request DTO
*/
@Data
public class BpmMessageSendWhenProcessInstanceApproveReqDTO {
/**
* 流程实例的编号
*/
@NotEmpty(message = "流程实例的编号不能为空")
private String processInstanceId;
/**
* 流程实例的名字
*/
@NotEmpty(message = "流程实例的名字不能为空")
private String processInstanceName;
@NotNull(message = "发起人的用户编号")
private Long startUserId;
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* BPM 发送流程实例被不通过 Request DTO
*/
@Data
public class BpmMessageSendWhenProcessInstanceRejectReqDTO {
/**
* 流程实例的编号
*/
@NotEmpty(message = "流程实例的编号不能为空")
private String processInstanceId;
/**
* 流程实例的名字
*/
@NotEmpty(message = "流程实例的名字不能为空")
private String processInstanceName;
@NotNull(message = "发起人的用户编号")
private Long startUserId;
/**
* 不通过理由
*/
@NotEmpty(message = "不通过理由不能为空")
private String comment;
}

View File

@ -6,7 +6,7 @@ import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
/** /**
* BPM 发送任务创建的 Request DTO * BPM 发送任务被分配 Request DTO
*/ */
@Data @Data
public class BpmMessageSendWhenTaskCreatedReqDTO { public class BpmMessageSendWhenTaskCreatedReqDTO {

View File

@ -2,6 +2,8 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.message.impl;
import cn.iocoder.yudao.adminserver.modules.bpm.enums.message.BpmMessageEnum; import cn.iocoder.yudao.adminserver.modules.bpm.enums.message.BpmMessageEnum;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.adminserver.modules.bpm.service.message.BpmMessageService;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO; import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -29,18 +31,37 @@ public class BpmMessageServiceImpl implements BpmMessageService {
@Value("${yudao.url.admin-ui}") @Value("${yudao.url.admin-ui}")
private String adminUiUrl; private String adminUiUrl;
@Override
public void sendMessageWhenProcessInstanceApprove(BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO) {
Map<String, Object> templateParams = new HashMap<>();
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
smsCoreService.sendSingleSmsToAdmin(null, reqDTO.getStartUserId(),
BpmMessageEnum.PROCESS_INSTANCE_APPROVE.getSmsCode(), templateParams);
}
@Override
public void sendMessageWhenProcessInstanceReject(BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO) {
Map<String, Object> templateParams = new HashMap<>();
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
templateParams.put("comment", reqDTO.getComment());
templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
smsCoreService.sendSingleSmsToAdmin(null, reqDTO.getStartUserId(),
BpmMessageEnum.PROCESS_INSTANCE_REJECT.getSmsCode(), templateParams);
}
@Override @Override
public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) { public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) {
Map<String, Object> templateParams = new HashMap<>(); Map<String, Object> templateParams = new HashMap<>();
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName()); templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
templateParams.put("taskName", reqDTO.getTaskName()); templateParams.put("taskName", reqDTO.getTaskName());
templateParams.put("startUserNickname", reqDTO.getStartUserNickname()); templateParams.put("startUserNickname", reqDTO.getStartUserNickname());
templateParams.put("taskDetailUrl", getTaskDetailUrl(reqDTO.getTaskId())); templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
smsCoreService.sendSingleSmsToAdmin(null, reqDTO.getAssigneeUserId(), smsCoreService.sendSingleSmsToAdmin(null, reqDTO.getAssigneeUserId(),
BpmMessageEnum.TASK_ASSIGNED.getSmsCode(), templateParams); BpmMessageEnum.TASK_ASSIGNED.getSmsCode(), templateParams);
} }
private String getTaskDetailUrl(String taskId) { private String getProcessInstanceDetailUrl(String taskId) {
return adminUiUrl + "bpm/process-instance/detail?id=" + taskId; return adminUiUrl + "bpm/process-instance/detail?id=" + taskId;
} }

View File

@ -46,15 +46,6 @@ public interface BpmProcessInstanceService {
@Deprecated @Deprecated
void deleteProcessInstance(String id, String reason); void deleteProcessInstance(String id, String reason);
/**
* 更新流程实例的结果
* 1. 如果更新为已拒绝时会进行任务的删除
*
* @param id 流程编号
* @param result 结果{@link BpmProcessInstanceResultEnum}
*/
void updateProcessInstanceResult(String id, Integer result);
/** /**
* 获得流程实例的分页 * 获得流程实例的分页
* *
@ -153,4 +144,12 @@ public interface BpmProcessInstanceService {
*/ */
void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance); void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance);
/**
* 更新 ProcessInstance 拓展记录为不通过
*
* @param id 流程编号
* @param comment 理由例如说审批不通过时需要传递该值
*/
void updateProcessInstanceExtReject(String id, String comment);
} }

View File

@ -2,9 +2,9 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.*; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.*;
import cn.iocoder.yudao.adminserver.modules.bpm.convert.message.BpmMessageConvert;
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmProcessInstanceConvert;
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
@ -13,6 +13,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceDel
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceStatusEnum;
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.BpmMessageService;
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService; import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService; import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
@ -28,7 +29,6 @@ import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task; import org.activiti.engine.task.Task;
import org.mapstruct.ap.shaded.freemarker.template.utility.StringUtil;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -72,6 +72,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
private BpmTaskService taskService; private BpmTaskService taskService;
@Resource @Resource
private BpmProcessDefinitionService processDefinitionService; private BpmProcessDefinitionService processDefinitionService;
@Resource
private BpmMessageService messageService;
@Resource @Resource
private BpmProcessInstanceExtMapper processInstanceExtMapper; private BpmProcessInstanceExtMapper processInstanceExtMapper;
@ -132,18 +134,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
runtimeService.deleteProcessInstance(id, reason); runtimeService.deleteProcessInstance(id, reason);
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void updateProcessInstanceResult(String id, Integer result) {
// 删除流程实例以实现驳回任务时取消整个审批流程
if (Objects.equals(result, BpmProcessInstanceResultEnum.REJECT.getResult())) {
deleteProcessInstance(id, BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.getReason());
}
// 更新 status + result
processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(id)
.setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()).setResult(result));
}
@Override @Override
public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
BpmProcessInstanceMyPageReqVO pageReqVO) { BpmProcessInstanceMyPageReqVO pageReqVO) {
@ -251,6 +241,26 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
.setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus()) .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全说明审批通过 .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); // 如果正常完全说明审批通过
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO); processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
// 发送流程被通过的消息
messageService.sendMessageWhenProcessInstanceApprove(BpmMessageConvert.INSTANCE.convert(instance));
}
@Transactional(rollbackFor = Exception.class)
public void updateProcessInstanceExtReject(String id, String comment) {
ProcessInstance processInstance = getProcessInstance(id);
// 删除流程实例以实现驳回任务时取消整个审批流程
deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.getReason(), comment));
// 更新 status + result
// 注意不能和上面的逻辑更换位置因为 deleteProcessInstance 会触发流程的取消进而调用 updateProcessInstanceExtCancel 方法
// 设置 result BpmProcessInstanceStatusEnum.CANCEL显然和 result 不一定是一致的
processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(id)
.setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
.setResult(BpmProcessInstanceResultEnum.REJECT.getResult()));
// 发送流程被不通过的消息
messageService.sendMessageWhenProcessInstanceReject(BpmMessageConvert.INSTANCE.convert(processInstance, comment));
} }
} }

View File

@ -1,7 +1,6 @@
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl; package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*;
import cn.iocoder.yudao.adminserver.modules.bpm.convert.message.BpmMessageConvert; import cn.iocoder.yudao.adminserver.modules.bpm.convert.message.BpmMessageConvert;
@ -38,7 +37,6 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -254,8 +252,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
} }
// 更新流程实例为不通过 // 更新流程实例为不通过
processInstanceService.updateProcessInstanceResult(instance.getProcessInstanceId(), processInstanceService.updateProcessInstanceExtReject(instance.getProcessInstanceId(), reqVO.getComment());
BpmProcessInstanceResultEnum.REJECT.getResult());
// 更新任务拓展表为不通过 // 更新任务拓展表为不通过
taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId()) taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(task.getId())