bpm 增加任务分配到指定人时,发送短信通知

This commit is contained in:
YunaiV 2022-01-21 22:53:43 +08:00
parent d839adedff
commit e3b86b3d7a
9 changed files with 215 additions and 0 deletions

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.adminserver.modules.bpm.convert.message;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
import org.activiti.api.task.model.Task;
import org.activiti.engine.runtime.ProcessInstance;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface BpmMessageConvert {
BpmMessageConvert INSTANCE = Mappers.getMapper(BpmMessageConvert.class);
default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, SysUserDO startUser, Task task) {
BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO();
copyTo(processInstance, reqDTO);
copyTo(startUser, reqDTO);
copyTo(task, reqDTO);
return reqDTO;
}
@Mapping(source = "name", target = "processInstanceName")
void copyTo(ProcessInstance from, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);
@Mappings({
@Mapping(source = "id", target = "startUserId"),
@Mapping(source = "nickname", target = "startUserNickname")
})
void copyTo(SysUserDO from, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);
@Mappings({
@Mapping(source = "id", target = "taskId"),
@Mapping(source = "name", target = "taskName"),
@Mapping(source = "assignee", target = "assigneeUserId")
})
void copyTo(Task task, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.adminserver.modules.bpm.enums.message;
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.sms.SysSmsTemplateDO;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Bpm 消息的枚举
*
* @author 芋道源码
*/
@AllArgsConstructor
@Getter
public enum BpmMessageEnum {
TASK_ASSIGNED("bpm_task_assigned"); // 任务被分配时发送给审批人
/**
* 短信模板的标识
*
* 关联 {@link SysSmsTemplateDO#getCode()}
*/
private final String smsCode;
}

View File

@ -53,6 +53,12 @@ public class BpmTaskEventListener<T extends RuntimeEvent<?, ?>>
return; return;
} }
// 审核人修改时进行拓展表并额外发送通知
if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED) {
taskService.updateTaskExtAssign(event.getEntity());
return;
}
// 其它事件进行更新拓展表 // 其它事件进行更新拓展表
taskService.updateTaskExt(event.getEntity()); taskService.updateTaskExt(event.getEntity());
} }

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.adminserver.modules.bpm.service.message;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
import javax.validation.Valid;
/**
* BPM 消息 Service 接口
*
* TODO 芋艿未来支持消息的可配置不同的流程在什么场景下需要发送什么消息消息的内容是什么
*
* @author 芋道源码
*/
public interface BpmMessageService {
void sendMessageWhenTaskAssigned(@Valid BpmMessageSendWhenTaskCreatedReqDTO reqDTO);
}

View File

@ -0,0 +1,46 @@
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 BpmMessageSendWhenTaskCreatedReqDTO {
/**
* 流程实例的编号
*/
@NotEmpty(message = "流程实例的编号不能为空")
private String processInstanceId;
/**
* 流程实例的名字
*/
@NotEmpty(message = "流程实例的名字不能为空")
private String processInstanceName;
@NotEmpty(message = "发起人的用户编号")
private String startUserId;
@NotEmpty(message = "发起人的昵称")
private String startUserNickname;
/**
* 流程任务的编号
*/
@NotEmpty(message = "流程任务的编号不能为空")
private String taskId;
/**
* 流程任务的名字
*/
@NotEmpty(message = "流程任务的名字不能为空")
private String taskName;
/**
* 审批人的用户编号
*/
@NotNull(message = "审批人的用户编号不能为空")
private Long assigneeUserId;
}

View File

@ -0,0 +1,47 @@
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.service.message.BpmMessageService;
import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
* BPM 消息 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
@Slf4j
public class BpmMessageServiceImpl implements BpmMessageService {
@Resource
private SysSmsCoreService smsCoreService;
@Value("${yudao.url.admin-ui}")
private String adminUiUrl;
@Override
public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) {
Map<String, Object> templateParams = new HashMap<>();
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
templateParams.put("taskName", reqDTO.getTaskName());
templateParams.put("startUserNickname", reqDTO.getStartUserNickname());
templateParams.put("taskDetailUrl", getTaskDetailUrl(reqDTO.getTaskId()));
smsCoreService.sendSingleSmsToAdmin(null, reqDTO.getAssigneeUserId(),
BpmMessageEnum.TASK_ASSIGNED.getSmsCode(), templateParams);
}
private String getTaskDetailUrl(String taskId) {
return adminUiUrl + "bpm/process-instance/detail?id=" + taskId;
}
}

View File

@ -126,6 +126,13 @@ public interface BpmTaskService {
*/ */
void updateTaskExt(org.activiti.api.task.model.Task task); void updateTaskExt(org.activiti.api.task.model.Task task);
/**
* 更新 Task 拓展记录并发送通知
*
* @param task 任务实体
*/
void updateTaskExtAssign(org.activiti.api.task.model.Task task);
/** /**
* 更新 Task 拓展记录为取消 * 更新 Task 拓展记录为取消
* *
@ -148,4 +155,5 @@ public interface BpmTaskService {
*/ */
List<BpmTaskExtDO> getTaskExtListByProcessInstanceId(String processInstanceId); List<BpmTaskExtDO> getTaskExtListByProcessInstanceId(String processInstanceId);
} }

View File

@ -1,12 +1,15 @@
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.task.BpmTaskConvert; import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert;
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO; import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmTaskExtMapper; import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmTaskExtMapper;
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.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;
@ -29,10 +32,13 @@ import org.activiti.engine.task.TaskQuery;
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;
import org.springframework.transaction.support.TransactionSynchronization;
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;
@ -61,6 +67,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
@Resource @Resource
@Lazy // 解决循环依赖 @Lazy // 解决循环依赖
private BpmProcessInstanceService processInstanceService; private BpmProcessInstanceService processInstanceService;
@Resource
private BpmMessageService messageService;
@Resource @Resource
private BpmTaskExtMapper taskExtMapper; private BpmTaskExtMapper taskExtMapper;
@ -277,6 +285,21 @@ public class BpmTaskServiceImpl implements BpmTaskService {
taskExtMapper.updateByTaskId(taskExtDO); taskExtMapper.updateByTaskId(taskExtDO);
} }
@Override
public void updateTaskExtAssign(org.activiti.api.task.model.Task task) {
// 更新
updateTaskExt(task);
// 发送通知由于 Activiti 操作是在事务提交时批量执行操作所以直接查询会无法查询到 ProcessInstance所以这里是通过监听事务的提交来实现
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
SysUserDO startUser = userService.getUser(Long.valueOf(processInstance.getStartUserId()));
messageService.sendMessageWhenTaskAssigned(BpmMessageConvert.INSTANCE.convert(processInstance, startUser, task));
}
});
}
@Override @Override
public void updateTaskExtCancel(org.activiti.api.task.model.Task task) { public void updateTaskExtCancel(org.activiti.api.task.model.Task task) {
BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task) BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)

View File

@ -72,5 +72,7 @@ yudao:
- cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants - cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants
tenant: # 多租户相关配置项 tenant: # 多租户相关配置项
tables: # 配置需要开启多租户的表;如果实体已经继承 TenantBaseDO 类,则无需重复配置 tables: # 配置需要开启多租户的表;如果实体已经继承 TenantBaseDO 类,则无需重复配置
url:
admin-ui: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
debug: false debug: false