mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	bpm 增加任务分配到指定人时,发送短信通知
This commit is contained in:
		@@ -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);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -53,6 +53,12 @@ public class BpmTaskEventListener<T extends RuntimeEvent<?, ?>>
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 审核人修改时,进行拓展表,并额外发送通知
 | 
			
		||||
        if (event.getEventType() == TaskRuntimeEvent.TaskEvents.TASK_ASSIGNED) {
 | 
			
		||||
            taskService.updateTaskExtAssign(event.getEntity());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 其它事件,进行更新拓展表
 | 
			
		||||
        taskService.updateTaskExt(event.getEntity());
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -126,6 +126,13 @@ public interface BpmTaskService {
 | 
			
		||||
     */
 | 
			
		||||
    void updateTaskExt(org.activiti.api.task.model.Task task);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 更新 Task 拓展记录,并发送通知
 | 
			
		||||
     *
 | 
			
		||||
     * @param task 任务实体
 | 
			
		||||
     */
 | 
			
		||||
    void updateTaskExtAssign(org.activiti.api.task.model.Task task);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 更新 Task 拓展记录为取消
 | 
			
		||||
     *
 | 
			
		||||
@@ -148,4 +155,5 @@ public interface BpmTaskService {
 | 
			
		||||
     */
 | 
			
		||||
    List<BpmTaskExtDO> getTaskExtListByProcessInstanceId(String processInstanceId);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,15 @@
 | 
			
		||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.collection.CollUtil;
 | 
			
		||||
import cn.hutool.core.thread.ThreadUtil;
 | 
			
		||||
import cn.hutool.core.util.StrUtil;
 | 
			
		||||
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.dal.dataobject.task.BpmTaskExtDO;
 | 
			
		||||
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.service.message.BpmMessageService;
 | 
			
		||||
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.system.dal.dataobject.dept.SysDeptDO;
 | 
			
		||||
@@ -29,10 +32,13 @@ import org.activiti.engine.task.TaskQuery;
 | 
			
		||||
import org.springframework.context.annotation.Lazy;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
import org.springframework.transaction.support.TransactionSynchronization;
 | 
			
		||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.validation.Valid;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
			
		||||
@@ -61,6 +67,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
 | 
			
		||||
    @Resource
 | 
			
		||||
    @Lazy // 解决循环依赖
 | 
			
		||||
    private BpmProcessInstanceService processInstanceService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private BpmMessageService messageService;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private BpmTaskExtMapper taskExtMapper;
 | 
			
		||||
@@ -277,6 +285,21 @@ public class BpmTaskServiceImpl implements BpmTaskService {
 | 
			
		||||
        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
 | 
			
		||||
    public void updateTaskExtCancel(org.activiti.api.task.model.Task task) {
 | 
			
		||||
        BpmTaskExtDO taskExtDO = BpmTaskConvert.INSTANCE.convert(task)
 | 
			
		||||
 
 | 
			
		||||
@@ -72,5 +72,7 @@ yudao:
 | 
			
		||||
      - cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants
 | 
			
		||||
  tenant: # 多租户相关配置项
 | 
			
		||||
    tables: # 配置需要开启多租户的表;如果实体已经继承 TenantBaseDO 类,则无需重复配置
 | 
			
		||||
  url:
 | 
			
		||||
    admin-ui: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
 | 
			
		||||
 | 
			
		||||
debug: false
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user