Commit e3b86b3d7a58b34bcb6e12e48beb21784a7cdf24

Authored by YunaiV
1 parent d839aded

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

yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/message/BpmMessageConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.convert.message;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
  4 +import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
  5 +import org.activiti.api.task.model.Task;
  6 +import org.activiti.engine.runtime.ProcessInstance;
  7 +import org.mapstruct.Mapper;
  8 +import org.mapstruct.Mapping;
  9 +import org.mapstruct.MappingTarget;
  10 +import org.mapstruct.Mappings;
  11 +import org.mapstruct.factory.Mappers;
  12 +
  13 +@Mapper
  14 +public interface BpmMessageConvert {
  15 +
  16 + BpmMessageConvert INSTANCE = Mappers.getMapper(BpmMessageConvert.class);
  17 +
  18 + default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, SysUserDO startUser, Task task) {
  19 + BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO();
  20 + copyTo(processInstance, reqDTO);
  21 + copyTo(startUser, reqDTO);
  22 + copyTo(task, reqDTO);
  23 + return reqDTO;
  24 + }
  25 + @Mapping(source = "name", target = "processInstanceName")
  26 + void copyTo(ProcessInstance from, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);
  27 + @Mappings({
  28 + @Mapping(source = "id", target = "startUserId"),
  29 + @Mapping(source = "nickname", target = "startUserNickname")
  30 + })
  31 + void copyTo(SysUserDO from, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);
  32 + @Mappings({
  33 + @Mapping(source = "id", target = "taskId"),
  34 + @Mapping(source = "name", target = "taskName"),
  35 + @Mapping(source = "assignee", target = "assigneeUserId")
  36 + })
  37 + void copyTo(Task task, @MappingTarget BpmMessageSendWhenTaskCreatedReqDTO to);
  38 +
  39 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/message/BpmMessageEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.enums.message;
  2 +
  3 +import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.sms.SysSmsTemplateDO;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +/**
  8 + * Bpm 消息的枚举
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +@AllArgsConstructor
  13 +@Getter
  14 +public enum BpmMessageEnum {
  15 +
  16 + TASK_ASSIGNED("bpm_task_assigned"); // 任务被分配时,发送给审批人
  17 +
  18 + /**
  19 + * 短信模板的标识
  20 + *
  21 + * 关联 {@link SysSmsTemplateDO#getCode()}
  22 + */
  23 + private final String smsCode;
  24 +
  25 +
  26 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/listener/BpmTaskEventListener.java
... ... @@ -53,6 +53,12 @@ public class BpmTaskEventListener<T extends RuntimeEvent<?, ?>>
53 53 return;
54 54 }
55 55  
  56 + // 审核人修改时,进行拓展表,并额外发送通知
  57 + if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED) {
  58 + taskService.updateTaskExtAssign(event.getEntity());
  59 + return;
  60 + }
  61 +
56 62 // 其它事件,进行更新拓展表
57 63 taskService.updateTaskExt(event.getEntity());
58 64 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/message/BpmMessageService.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.service.message;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
  4 +
  5 +import javax.validation.Valid;
  6 +
  7 +/**
  8 + * BPM 消息 Service 接口
  9 + *
  10 + * TODO 芋艿:未来支持消息的可配置;不同的流程,在什么场景下,需要发送什么消息,消息的内容是什么;
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface BpmMessageService {
  15 +
  16 + void sendMessageWhenTaskAssigned(@Valid BpmMessageSendWhenTaskCreatedReqDTO reqDTO);
  17 +
  18 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/message/dto/BpmMessageSendWhenTaskCreatedReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import javax.validation.constraints.NotEmpty;
  6 +import javax.validation.constraints.NotNull;
  7 +
  8 +/**
  9 + * BPM 发送任务创建的 Request DTO
  10 + */
  11 +@Data
  12 +public class BpmMessageSendWhenTaskCreatedReqDTO {
  13 +
  14 + /**
  15 + * 流程实例的编号
  16 + */
  17 + @NotEmpty(message = "流程实例的编号不能为空")
  18 + private String processInstanceId;
  19 + /**
  20 + * 流程实例的名字
  21 + */
  22 + @NotEmpty(message = "流程实例的名字不能为空")
  23 + private String processInstanceName;
  24 + @NotEmpty(message = "发起人的用户编号")
  25 + private String startUserId;
  26 + @NotEmpty(message = "发起人的昵称")
  27 + private String startUserNickname;
  28 +
  29 + /**
  30 + * 流程任务的编号
  31 + */
  32 + @NotEmpty(message = "流程任务的编号不能为空")
  33 + private String taskId;
  34 + /**
  35 + * 流程任务的名字
  36 + */
  37 + @NotEmpty(message = "流程任务的名字不能为空")
  38 + private String taskName;
  39 +
  40 + /**
  41 + * 审批人的用户编号
  42 + */
  43 + @NotNull(message = "审批人的用户编号不能为空")
  44 + private Long assigneeUserId;
  45 +
  46 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/message/impl/BpmMessageServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.service.message.impl;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.bpm.enums.message.BpmMessageEnum;
  4 +import cn.iocoder.yudao.adminserver.modules.bpm.service.message.BpmMessageService;
  5 +import cn.iocoder.yudao.adminserver.modules.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
  6 +import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.beans.factory.annotation.Value;
  9 +import org.springframework.stereotype.Service;
  10 +import org.springframework.validation.annotation.Validated;
  11 +
  12 +import javax.annotation.Resource;
  13 +import java.util.HashMap;
  14 +import java.util.Map;
  15 +
  16 +/**
  17 + * BPM 消息 Service 实现类
  18 + *
  19 + * @author 芋道源码
  20 + */
  21 +@Service
  22 +@Validated
  23 +@Slf4j
  24 +public class BpmMessageServiceImpl implements BpmMessageService {
  25 +
  26 + @Resource
  27 + private SysSmsCoreService smsCoreService;
  28 +
  29 + @Value("${yudao.url.admin-ui}")
  30 + private String adminUiUrl;
  31 +
  32 + @Override
  33 + public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) {
  34 + Map<String, Object> templateParams = new HashMap<>();
  35 + templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
  36 + templateParams.put("taskName", reqDTO.getTaskName());
  37 + templateParams.put("startUserNickname", reqDTO.getStartUserNickname());
  38 + templateParams.put("taskDetailUrl", getTaskDetailUrl(reqDTO.getTaskId()));
  39 + smsCoreService.sendSingleSmsToAdmin(null, reqDTO.getAssigneeUserId(),
  40 + BpmMessageEnum.TASK_ASSIGNED.getSmsCode(), templateParams);
  41 + }
  42 +
  43 + private String getTaskDetailUrl(String taskId) {
  44 + return adminUiUrl + "bpm/process-instance/detail?id=" + taskId;
  45 + }
  46 +
  47 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmTaskService.java
... ... @@ -127,6 +127,13 @@ public interface BpmTaskService {
127 127 void updateTaskExt(org.activiti.api.task.model.Task task);
128 128  
129 129 /**
  130 + * 更新 Task 拓展记录,并发送通知
  131 + *
  132 + * @param task 任务实体
  133 + */
  134 + void updateTaskExtAssign(org.activiti.api.task.model.Task task);
  135 +
  136 + /**
130 137 * 更新 Task 拓展记录为取消
131 138 *
132 139 * @param task 任务实体
... ... @@ -148,4 +155,5 @@ public interface BpmTaskService {
148 155 */
149 156 List<BpmTaskExtDO> getTaskExtListByProcessInstanceId(String processInstanceId);
150 157  
  158 +
151 159 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java
1 1 package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.thread.ThreadUtil;
4 5 import cn.hutool.core.util.StrUtil;
5 6 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*;
  7 +import cn.iocoder.yudao.adminserver.modules.bpm.convert.message.BpmMessageConvert;
6 8 import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert;
7 9 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO;
8 10 import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmTaskExtMapper;
9 11 import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
  12 +import cn.iocoder.yudao.adminserver.modules.bpm.service.message.BpmMessageService;
10 13 import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
11 14 import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmTaskService;
12 15 import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
... ... @@ -29,10 +32,13 @@ import org.activiti.engine.task.TaskQuery;
29 32 import org.springframework.context.annotation.Lazy;
30 33 import org.springframework.stereotype.Service;
31 34 import org.springframework.transaction.annotation.Transactional;
  35 +import org.springframework.transaction.support.TransactionSynchronization;
  36 +import org.springframework.transaction.support.TransactionSynchronizationManager;
32 37  
33 38 import javax.annotation.Resource;
34 39 import javax.validation.Valid;
35 40 import java.util.*;
  41 +import java.util.concurrent.TimeUnit;
36 42  
37 43 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
38 44 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -61,6 +67,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
61 67 @Resource
62 68 @Lazy // 解决循环依赖
63 69 private BpmProcessInstanceService processInstanceService;
  70 + @Resource
  71 + private BpmMessageService messageService;
64 72  
65 73 @Resource
66 74 private BpmTaskExtMapper taskExtMapper;
... ... @@ -278,6 +286,21 @@ public class BpmTaskServiceImpl implements BpmTaskService {
278 286 }
279 287  
280 288 @Override
  289 + public void updateTaskExtAssign(org.activiti.api.task.model.Task task) {
  290 + // 更新
  291 + updateTaskExt(task);
  292 + // 发送通知。由于 Activiti 操作是在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。
  293 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
  294 + @Override
  295 + public void afterCommit() {
  296 + ProcessInstance processInstance = processInstanceService.getProcessInstance(task.getProcessInstanceId());
  297 + SysUserDO startUser = userService.getUser(Long.valueOf(processInstance.getStartUserId()));
  298 + messageService.sendMessageWhenTaskAssigned(BpmMessageConvert.INSTANCE.convert(processInstance, startUser, task));
  299 + }
  300 + });
  301 + }
  302 +
  303 + @Override
281 304 public void updateTaskExtCancel(org.activiti.api.task.model.Task task) {
282 305 BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)
283 306 .setEndTime(new Date()) // 由于 Task 里没有办法拿到 endTime,所以这里设置
... ...
yudao-admin-server/src/main/resources/application.yaml
... ... @@ -72,5 +72,7 @@ yudao:
72 72 - cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants
73 73 tenant: # 多租户相关配置项
74 74 tables: # 配置需要开启多租户的表;如果实体已经继承 TenantBaseDO 类,则无需重复配置
  75 + url:
  76 + admin-ui: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
75 77  
76 78 debug: false
... ...