Commit e3b86b3d7a58b34bcb6e12e48beb21784a7cdf24
1 parent
d839aded
bpm 增加任务分配到指定人时,发送短信通知
Showing
9 changed files
with
215 additions
and
0 deletions
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 | ... | ... |