Browse Source

增加 BpmProcessInstanceResultEvent 实现,实现自定义的流程实例的状态的监听

YunaiV 3 years ago
parent
commit
5437775172
15 changed files with 224 additions and 64 deletions
  1. 11 8
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/BpmOALeaveCreateReqVO.java
  2. 19 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmProcessInstanceConvert.java
  3. 2 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java
  4. 7 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/config/BpmActivitiConfiguration.java
  5. 44 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/event/BpmProcessInstanceResultEvent.java
  6. 34 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/event/BpmProcessInstanceResultEventListener.java
  7. 24 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/event/BpmProcessInstanceResultEventPublisher.java
  8. 6 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/event/package-info.java
  9. 0 3
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java
  10. 8 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/BpmOALeaveService.java
  11. 0 40
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/LeaveApplyEndProcessor.java
  12. 7 8
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/impl/OALeaveServiceImpl.java
  13. 32 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/listener/BpmOALeaveResultListener.java
  14. 0 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java
  15. 30 3
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java

+ 11 - 8
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/oa/vo/BpmOALeaveCreateReqVO.java

@@ -1,18 +1,21 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo;
 
-import lombok.*;
-import io.swagger.annotations.*;
-import org.springframework.format.annotation.DateTimeFormat;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
 
-import javax.validation.constraints.NotNull;
-import java.util.Date;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+import javax.validation.constraints.AssertTrue;
 
 @ApiModel("请假申请创建 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
 public class BpmOALeaveCreateReqVO extends BpmOALeaveBaseVO {
+
+    @AssertTrue(message = "结束时间,需要在开始时间之后")
+    public boolean isEndTimeValid() {
+        return !getEndTime().before(getStartTime());
+    }
+
 }

+ 19 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmProcessInstanceConvert.java

@@ -5,6 +5,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmP
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.BpmTaskRespVO;
 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.framework.activiti.core.event.BpmProcessInstanceResultEvent;
 import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
 import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -98,4 +99,22 @@ public interface BpmProcessInstanceConvert {
     void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to);
     BpmProcessInstanceRespVO.User convert2(SysUserDO bean);
 
+    default BpmProcessInstanceResultEvent convert(Object source, ProcessInstance instance, Integer result) {
+        BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
+        event.setId(instance.getId());
+        event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
+        event.setBusinessKey(instance.getBusinessKey());
+        event.setResult(result);
+        return event;
+    }
+
+    default BpmProcessInstanceResultEvent convert(Object source, HistoricProcessInstance instance, Integer result) {
+        BpmProcessInstanceResultEvent event = new BpmProcessInstanceResultEvent(source);
+        event.setId(instance.getId());
+        event.setProcessDefinitionKey(instance.getProcessDefinitionKey());
+        event.setBusinessKey(instance.getBusinessKey());
+        event.setResult(result);
+        return event;
+    }
+
 }

+ 2 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/task/BpmProcessInstanceDeleteReasonEnum.java

@@ -13,7 +13,8 @@ import lombok.Getter;
 @AllArgsConstructor
 public enum BpmProcessInstanceDeleteReasonEnum {
 
-    REJECT_TASK("不通过任务,原因:{}"); // 修改文案时,需要注意 isRejectReason 方法
+    REJECT_TASK("不通过任务,原因:{}"), // 修改文案时,需要注意 isRejectReason 方法
+    CANCEL_TASK("主动取消任务,原因:{}");
 
     private final String reason;
 

+ 7 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/config/BpmActivitiConfiguration.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.config;
 
 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.BpmActivityBehaviorFactory;
 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.script.BpmTaskAssignScript;
+import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEventPublisher;
 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.identity.EmptyUserGroupManager;
 import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener.BpmTackActivitiEventListener;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskAssignRuleService;
@@ -11,6 +12,7 @@ import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermiss
 import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
 import org.activiti.api.runtime.shared.identity.UserGroupManager;
 import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -71,4 +73,9 @@ public class BpmActivitiConfiguration {
         return bpmActivityBehaviorFactory;
     }
 
+    @Bean
+    public BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher(ApplicationEventPublisher publisher) {
+        return new BpmProcessInstanceResultEventPublisher(publisher);
+    }
+
 }

+ 44 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/event/BpmProcessInstanceResultEvent.java

@@ -0,0 +1,44 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
+import lombok.Data;
+import org.springframework.context.ApplicationEvent;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 流程实例的结果发生变化的 Event
+ * 定位:由于额外增加了 {@link BpmProcessInstanceExtDO#getResult()} 结果,所以增加该事件
+ *
+ * @author 芋道源码
+ */
+@SuppressWarnings("ALL")
+@Data
+public class BpmProcessInstanceResultEvent extends ApplicationEvent {
+
+    /**
+     * 流程实例的编号
+     */
+    @NotNull(message = "流程实例的编号不能为空")
+    private String id;
+    /**
+     * 流程实例的 key
+     */
+    @NotNull(message = "流程实例的 key 不能为空")
+    private String processDefinitionKey;
+    /**
+     * 流程实例的结果
+     */
+    @NotNull(message = "流程实例的结果不能为空")
+    private Integer result;
+    /**
+     * 流程实例对应的业务标识
+     * 例如说,请假
+     */
+    private String businessKey;
+
+    public BpmProcessInstanceResultEvent(Object source) {
+        super(source);
+    }
+
+}

+ 34 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/event/BpmProcessInstanceResultEventListener.java

@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event;
+
+import cn.hutool.core.util.StrUtil;
+import org.springframework.context.ApplicationListener;
+
+/**
+ * {@link BpmProcessInstanceResultEvent} 的监听器
+ *
+ * @author 芋道源码
+ */
+public abstract class BpmProcessInstanceResultEventListener
+        implements ApplicationListener<BpmProcessInstanceResultEvent> {
+
+    @Override
+    public final void onApplicationEvent(BpmProcessInstanceResultEvent event) {
+        if (!StrUtil.equals(event.getProcessDefinitionKey(), getProcessDefinitionKey())) {
+            return;
+        }
+        onEvent(event);
+    }
+
+    /**
+     * @return 返回监听的流程定义 Key
+     */
+    protected abstract String getProcessDefinitionKey();
+
+    /**
+     * 处理事件
+     *
+     * @param event 事件
+     */
+    protected abstract void onEvent(BpmProcessInstanceResultEvent event);
+
+}

+ 24 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/event/BpmProcessInstanceResultEventPublisher.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event;
+
+import lombok.AllArgsConstructor;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.Valid;
+
+/**
+ * {@link BpmProcessInstanceResultEvent} 的生产者
+ *
+ * @author 芋道源码
+ */
+@AllArgsConstructor
+@Validated
+public class BpmProcessInstanceResultEventPublisher {
+
+    private final ApplicationEventPublisher publisher;
+
+    public void sendProcessInstanceResultEvent(@Valid BpmProcessInstanceResultEvent event) {
+        publisher.publishEvent(event);
+    }
+
+}

+ 6 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/event/package-info.java

@@ -0,0 +1,6 @@
+/**
+ * 自定义 Event 实现,提供方便业务接入的 Listener!
+ *
+ * @author 芋道源码
+ */
+package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event;

+ 0 - 3
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java

@@ -2,10 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
 import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmModelFormTypeEnum;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
 import lombok.Data;
 
 import javax.validation.constraints.AssertTrue;

+ 8 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/BpmOALeaveService.java

@@ -24,6 +24,14 @@ public interface BpmOALeaveService {
      */
     Long createLeave(Long userId, @Valid BpmOALeaveCreateReqVO createReqVO);
 
+    /**
+     * 更新请假申请的状态
+     *
+     * @param id 编号
+     * @param result 结果
+     */
+    void updateLeaveResult(Long id, Integer result);
+
     /**
      * 删除请假申请
      *

+ 0 - 40
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/LeaveApplyEndProcessor.java

@@ -1,40 +0,0 @@
-package cn.iocoder.yudao.adminserver.modules.bpm.service.oa;
-
-import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.OALeaveDO;
-import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.oa.BpmOALeaveMapper;
-import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceResultEnum;
-import org.activiti.engine.delegate.DelegateExecution;
-import org.activiti.engine.delegate.ExecutionListener;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.Resource;
-import java.util.Objects;
-
-
-/**
- * 请假流程结束流程监听处理服务, 根据请假申请审批通过,还是未通过, 更新请假表单
- */
-@Component
-public class LeaveApplyEndProcessor implements ExecutionListener {
-
-    @Resource
-    private BpmOALeaveMapper leaveMapper;
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void notify(DelegateExecution delegateExecution) {
-        final String businessKey = delegateExecution.getProcessInstanceBusinessKey();
-        final Object approved = delegateExecution.getVariable("approved");
-        OALeaveDO updateDo = new OALeaveDO();
-        updateDo.setId(Long.valueOf(businessKey));
-        if (Objects.equals(approved, true)) {
-            updateDo.setResult(BpmProcessInstanceResultEnum.APPROVE.getResult());
-        } else {
-            updateDo.setResult(BpmProcessInstanceResultEnum.REJECT.getResult());
-        }
-
-        leaveMapper.updateById(updateDo);
-    }
-
-}

+ 7 - 8
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/impl/OALeaveServiceImpl.java

@@ -34,7 +34,7 @@ public class OALeaveServiceImpl implements BpmOALeaveService {
     /**
      * OA 请假对应的流程定义 KEY
      */
-    private static final String PROCESS_KEY = "oa_leave";
+    public static final String PROCESS_KEY = "oa_leave";
 
     @Resource
     private BpmOALeaveMapper leaveMapper;
@@ -45,14 +45,8 @@ public class OALeaveServiceImpl implements BpmOALeaveService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long createLeave(Long userId, BpmOALeaveCreateReqVO createReqVO) {
-        // TODO 芋道源码
-        // 校验是否超过请假天数的上限;
-        long day = DateUtil.betweenDay(createReqVO.getStartTime(), createReqVO.getEndTime(), false);
-        if (day <= 0) {
-            throw ServiceExceptionUtil.exception(OA_DAY_LEAVE_ERROR);
-        }
-
         // 插入 OA 请假单
+        long day = DateUtil.betweenDay(createReqVO.getStartTime(), createReqVO.getEndTime(), false);
         OALeaveDO leave = OALeaveConvert.INSTANCE.convert(createReqVO).setUserId(userId).setDay(day)
                 .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
         leaveMapper.insert(leave);
@@ -69,6 +63,11 @@ public class OALeaveServiceImpl implements BpmOALeaveService {
         return leave.getId();
     }
 
+    @Override
+    public void updateLeaveResult(Long id, Integer result) {
+        leaveMapper.updateById(new OALeaveDO().setId(id).setResult(result));
+    }
+
     @Override
     public void cancelLeave(Long id) {
         // TODO 需要重新实现

+ 32 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/listener/BpmOALeaveResultListener.java

@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.adminserver.modules.bpm.service.oa.listener;
+
+import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEvent;
+import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEventListener;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.oa.BpmOALeaveService;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.oa.impl.OALeaveServiceImpl;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * OA 请假单的结果的监听器实现类
+ *
+ * @author 芋道源码
+ */
+@Component
+public class BpmOALeaveResultListener extends BpmProcessInstanceResultEventListener {
+
+    @Resource
+    private BpmOALeaveService leaveService;
+
+    @Override
+    protected String getProcessDefinitionKey() {
+        return OALeaveServiceImpl.PROCESS_KEY;
+    }
+
+    @Override
+    protected void onEvent(BpmProcessInstanceResultEvent event) {
+        leaveService.updateLeaveResult(Long.parseLong(event.getBusinessKey()), event.getResult());
+    }
+
+}

+ 0 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java

@@ -152,7 +152,6 @@ public interface BpmProcessInstanceService {
      * 更新 ProcessInstance 拓展记录为完成
      *
      * @param instance 流程任务
-     * @param reason 原因
      */
     void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance);
 

+ 30 - 3
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java

@@ -12,6 +12,9 @@ import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.task.BpmProcessInstanc
 import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
 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.framework.activiti.core.event.BpmProcessInstanceResultEvent;
+import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEventListener;
+import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.event.BpmProcessInstanceResultEventPublisher;
 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;
@@ -76,6 +79,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
     @Resource
     private BpmMessageService messageService;
 
+    @Resource
+    private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher;
+
     @Resource
     private BpmProcessInstanceExtMapper processInstanceExtMapper;
 
@@ -141,7 +147,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
         }
 
         // 通过删除流程实例,实现流程实例的取消
-        runtimeService.deleteProcessInstance(cancelReqVO.getId(), cancelReqVO.getReason());
+        runtimeService.deleteProcessInstance(cancelReqVO.getId(),
+                BpmProcessInstanceDeleteReasonEnum.CANCEL_TASK.format(cancelReqVO.getReason()));
     }
 
     @Override
@@ -247,16 +254,26 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
             return;
         }
 
+        // 需要主动查询,因为 instance 只有 id 属性
+        ProcessInstance processInstance = getProcessInstance(instance.getId());
         // 更新拓展表
         BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)
                 .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
                 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
                 .setResult(BpmProcessInstanceResultEnum.CANCEL.getResult());
         processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
+
+        // 发送流程实例的状态事件
+        processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
+                BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
     }
 
     @Override
     public void updateProcessInstanceExtComplete(org.activiti.api.process.model.ProcessInstance instance) {
+        // 需要主动查询,因为 instance 只有 id 属性
+        // 另外,此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance
+        HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId());
+        // 更新拓展表
         BpmProcessInstanceExtDO instanceExtDO = BpmProcessInstanceConvert.INSTANCE.convert(instance)
                 .setEndTime(new Date()) // 由于 ProcessInstance 里没有办法拿到 endTime,所以这里设置
                 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
@@ -265,10 +282,15 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
 
         // 发送流程被通过的消息
         messageService.sendMessageWhenProcessInstanceApprove(BpmMessageConvert.INSTANCE.convert(instance));
+
+        // 发送流程实例的状态事件
+        processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
+                BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
     }
 
     @Transactional(rollbackFor = Exception.class)
     public void updateProcessInstanceExtReject(String id, String comment) {
+        // 需要主动查询,因为 instance 只有 id 属性
         ProcessInstance processInstance = getProcessInstance(id);
         // 删除流程实例,以实现驳回任务时,取消整个审批流程
         deleteProcessInstance(id, StrUtil.format(BpmProcessInstanceDeleteReasonEnum.REJECT_TASK.format(comment)));
@@ -276,12 +298,17 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
         // 更新 status + result
         // 注意,不能和上面的逻辑更换位置。因为 deleteProcessInstance 会触发流程的取消,进而调用 updateProcessInstanceExtCancel 方法,
         // 设置 result 为 BpmProcessInstanceStatusEnum.CANCEL,显然和 result 不一定是一致的
-        processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(id)
+        BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessInstanceId(id)
                 .setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
-                .setResult(BpmProcessInstanceResultEnum.REJECT.getResult()));
+                .setResult(BpmProcessInstanceResultEnum.REJECT.getResult());
+        processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
 
         // 发送流程被不通过的消息
         messageService.sendMessageWhenProcessInstanceReject(BpmMessageConvert.INSTANCE.convert(processInstance, comment));
+
+        // 发送流程实例的状态事件
+        processInstanceResultEventPublisher.sendProcessInstanceResultEvent(
+                BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, instanceExtDO.getResult()));
     }
 
 }