Commit 4d7ee1769f867da8b29fafa38c5d88f7daa4e3f5

Authored by YunaiV
1 parent e43039b0

1. 新增流程实例的拓展表

2. 将 Activiti 的 userId,统一使用 ActivitiUtils 进行设置
Showing 15 changed files with 186 additions and 38 deletions
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.java
... ... @@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
14 14 import javax.annotation.Resource;
15 15 import javax.validation.Valid;
16 16  
  17 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
17 18 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
18 19  
19 20 @Api(tags = "流程实例") // 流程实例,通过流程定义创建的一次“申请”
... ... @@ -28,8 +29,8 @@ public class BpmProcessInstanceController {
28 29 @PostMapping("/create")
29 30 @ApiOperation("新建流程实例")
30 31 public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {
31   -// return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
32   - processInstanceService.getMyProcessInstancePage(getLoginUserId());
  32 + return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
  33 +// processInstanceService.getMyProcessInstancePage(getLoginUserId());
33 34 return null;
34 35 }
35 36  
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/definition/BpmProcessDefinitionDO.java
... ... @@ -9,7 +9,7 @@ import org.activiti.engine.repository.ProcessDefinition;
9 9  
10 10 /**
11 11 * Bpm 流程定义的拓展表
12   - * 主要解决 主要进行 Activiti {@link ProcessDefinition} 不支持拓展字段,所以新建拓展表
  12 + * 主要解决 Activiti {@link ProcessDefinition} 不支持拓展字段,所以新建拓展表
13 13 *
14 14 * @author 芋道源码
15 15 */
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/BpmProcessInstanceExtDO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.ProcessInstanceResultEnum;
  4 +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.ProcessInstanceStatusEnum;
  5 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +import org.activiti.engine.history.HistoricProcessInstance;
  9 +import org.activiti.engine.runtime.ProcessInstance;
  10 +
  11 +/**
  12 + * Bpm 流程实例的拓展表
  13 + * 主要解决 Activiti {@link ProcessInstance} 和 {@link HistoricProcessInstance} 不支持拓展字段,所以新建拓展表
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName(value = "bpm_process_instance_ext", autoResultMap = true)
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class BpmProcessInstanceExtDO extends BaseDO {
  25 +
  26 + /**
  27 + * 发起流程的用户编号
  28 + *
  29 + * 冗余 {@link HistoricProcessInstance#getStartUserId()}
  30 + */
  31 + private Long userId;
  32 + /**
  33 + * 流程实例的名字
  34 + *
  35 + * 冗余 {@link ProcessInstance#getName()} 为了筛选
  36 + */
  37 + private String name;
  38 + /**
  39 + * 流程实例的编号
  40 + *
  41 + * 关联 {@link ProcessInstance#getId()}
  42 + */
  43 + private String processInstanceId;
  44 + /**
  45 + * 流程实例的状态
  46 + *
  47 + * 枚举 {@link ProcessInstanceStatusEnum}
  48 + */
  49 + private Integer status;
  50 + /**
  51 + * 结果
  52 + *
  53 + * 枚举 {@link ProcessInstanceResultEnum}
  54 + */
  55 + private Integer result;
  56 +
  57 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/package-info.java deleted
1   -/**
2   - * TODO 芋艿:工作流创建后的定义
3   - */
4   -package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task;
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/task/ProcessInstanceResultEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.enums.task;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Getter;
  5 +
  6 +/**
  7 + * 流程实例的结果
  8 + *
  9 + * @author jason
  10 + */
  11 +@Getter
  12 +@AllArgsConstructor
  13 +public enum ProcessInstanceResultEnum {
  14 +
  15 + PROCESS(1, "处理中"),
  16 + PASS(2, "通过"),
  17 + REJECT(3, "不通过"),
  18 + CANCEL(4, "撤销");
  19 +
  20 + /**
  21 + * 结果
  22 + */
  23 + private final Integer result;
  24 + /**
  25 + * 描述
  26 + */
  27 + private final String desc;
  28 +
  29 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/FlowStatusEnum.java renamed to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/task/ProcessInstanceStatusEnum.java
1   -package cn.iocoder.yudao.adminserver.modules.bpm.enums;
  1 +package cn.iocoder.yudao.adminserver.modules.bpm.enums.task;
2 2  
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Getter;
5 5  
6 6 /**
7   - * 流程状态
  7 + * 流程实例的结果
  8 + *
  9 + * @author 芋道源码
8 10 */
9 11 @Getter
10 12 @AllArgsConstructor
11   -public enum FlowStatusEnum {
  13 +public enum ProcessInstanceStatusEnum {
12 14  
13   - HANDLE(1, "处理中"),
14   -
15   - PASS(2, "审批通过"),
16   -
17   - REJECTED(3, "审批不通过");
  15 + RUNNING(1, "进行中"),
  16 + FINISH(2, "已完成");
18 17  
19 18 /**
20 19 * 状态
21 20 */
22   - private final Integer status;
23   -
24   -
  21 + private final Integer result;
25 22 /**
26 23 * 描述
27 24 */
28 25 private final String desc;
  26 +
29 27 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/LeaveApplyEndProcessor.java
... ... @@ -2,7 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.oa;
2 2  
3 3 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.OALeaveDO;
4 4 import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.oa.OALeaveMapper;
5   -import cn.iocoder.yudao.adminserver.modules.bpm.enums.FlowStatusEnum;
  5 +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.ProcessInstanceResultEnum;
6 6 import org.activiti.engine.delegate.DelegateExecution;
7 7 import org.activiti.engine.delegate.ExecutionListener;
8 8 import org.springframework.stereotype.Component;
... ... @@ -29,9 +29,9 @@ public class LeaveApplyEndProcessor implements ExecutionListener {
29 29 OALeaveDO updateDo = new OALeaveDO();
30 30 updateDo.setId(Long.valueOf(businessKey));
31 31 if (Objects.equals(approved, true)) {
32   - updateDo.setStatus(FlowStatusEnum.PASS.getStatus());
  32 + updateDo.setStatus(ProcessInstanceResultEnum.PASS.getResult());
33 33 } else {
34   - updateDo.setStatus(FlowStatusEnum.REJECTED.getStatus());
  34 + updateDo.setStatus(ProcessInstanceResultEnum.REJECT.getResult());
35 35 }
36 36  
37 37 leaveMapper.updateById(updateDo);
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/oa/impl/OALeaveServiceImpl.java
... ... @@ -6,7 +6,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.oa.vo.*;
6 6 import cn.iocoder.yudao.adminserver.modules.bpm.convert.oa.OALeaveConvert;
7 7 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.leave.OALeaveDO;
8 8 import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.oa.OALeaveMapper;
9   -import cn.iocoder.yudao.adminserver.modules.bpm.enums.FlowStatusEnum;
  9 +import cn.iocoder.yudao.adminserver.modules.bpm.enums.task.ProcessInstanceResultEnum;
10 10 import cn.iocoder.yudao.adminserver.modules.bpm.service.oa.OALeaveService;
11 11 import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysPostDO;
12 12 import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.dept.SysPostMapper;
... ... @@ -62,7 +62,7 @@ public class OALeaveServiceImpl implements OALeaveService {
62 62 public Long createLeave(OALeaveCreateReqVO createReqVO) {
63 63 // 插入 OA 请假单
64 64 OALeaveDO leave = OALeaveConvert.INSTANCE.convert(createReqVO);
65   - leave.setStatus(FlowStatusEnum.HANDLE.getStatus());
  65 + leave.setStatus(ProcessInstanceResultEnum.PROCESS.getResult());
66 66 // TODO @jason:应该是存储 userId??
67 67 leave.setUserId(SecurityFrameworkUtils.getLoginUser().getUsername());
68 68 leaveMapper.insert(leave);
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java
... ... @@ -13,7 +13,6 @@ import org.activiti.engine.RuntimeService;
13 13 import org.activiti.engine.TaskService;
14 14 import org.activiti.engine.history.HistoricProcessInstance;
15 15 import org.activiti.engine.history.HistoricProcessInstanceQuery;
16   -import org.activiti.engine.impl.identity.Authentication;
17 16 import org.activiti.engine.repository.ProcessDefinition;
18 17 import org.activiti.engine.runtime.ProcessInstance;
19 18 import org.activiti.engine.task.Task;
... ... @@ -70,12 +69,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
70 69 throw exception(PROCESS_DEFINITION_IS_SUSPENDED);
71 70 }
72 71  
73   - // 设置流程发起人
74   - Authentication.setAuthenticatedUserId(String.valueOf(userId));
75   -
76 72 // 创建流程实例
77 73 Map<String, Object> variables = createReqVO.getVariables();
78   - variables.put("INITIATOR", userId); // TODO 芋艿:初始化人员
79 74 ProcessInstance instance = runtimeService.startProcessInstanceById(createReqVO.getProcessDefinitionId(), variables);
80 75  
81 76 // 添加初始的评论 TODO 芋艿:在思考下
... ... @@ -97,6 +92,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
97 92 // id title 所属流程 当前审批环节 状态 结果 创建时间 提交申请时间 【标题、状态】「ActBusiness」
98 93 // id title 流程类别 流程版本 提交时间 流程状态 耗时 当前节点 办理 【标题、提交时间】「HistoricProcessInstanceQuery」
99 94  
  95 + // id title 所属流程 流程类别 创建时间 状态 当前审批环节 【标题、状态】
  96 +
100 97 runtimeService.createProcessInstanceQuery().list();
101 98 HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
102 99 .startedBy(String.valueOf(userId)) // 发起人是自己
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java
... ... @@ -25,7 +25,9 @@ public interface WebFilterOrderEnum {
25 25  
26 26 // Spring Security Filter 默认为 -100,可见 org.springframework.boot.autoconfigure.security.SecurityProperties 配置属性类
27 27  
28   - int TENANT_SECURITY_FILTER = -99; // 需要保证在 Spring Security 过滤器后
  28 + int TENANT_SECURITY_FILTER = -99; // 需要保证在 Spring Security 过滤器后面
  29 +
  30 + int ACTIVITI_FILTER = -98; // 需要保证在 Spring Security 过滤后面
29 31  
30 32 int DEMO_FILTER = Integer.MAX_VALUE;
31 33  
... ...
yudao-framework/yudao-spring-boot-starter-activiti/pom.xml
... ... @@ -37,6 +37,14 @@
37 37 <artifactId>yudao-common</artifactId>
38 38 </dependency>
39 39  
  40 + <!-- Web 相关 -->
  41 + <dependency>
  42 + <groupId>cn.iocoder.boot</groupId>
  43 + <artifactId>yudao-spring-boot-starter-security</artifactId>
  44 + </dependency>
  45 +
  46 +
  47 +
40 48 <dependency>
41 49 <groupId>org.mybatis</groupId>
42 50 <artifactId>mybatis</artifactId>
... ... @@ -72,6 +80,7 @@
72 80 <artifactId>activiti-image-generator</artifactId>
73 81 <version>${activiti.version}</version>
74 82 </dependency>
  83 +
75 84 </dependencies>
76 85  
77 86 </project>
... ...
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/config/YudaoActivitiConfiguration.java
1 1 package cn.iocoder.yudao.framework.activiti.config;
2 2  
  3 +import cn.iocoder.yudao.framework.activiti.core.web.ActivitiWebFilter;
  4 +import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
3 5 import org.activiti.image.ProcessDiagramGenerator;
4 6 import org.activiti.image.impl.DefaultProcessDiagramGenerator;
5 7 import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
6 8 import org.apache.ibatis.session.SqlSessionFactory;
  9 +import org.springframework.boot.web.servlet.FilterRegistrationBean;
7 10 import org.springframework.context.annotation.Bean;
8 11 import org.springframework.context.annotation.Configuration;
9 12  
... ... @@ -26,4 +29,12 @@ public class YudaoActivitiConfiguration {
26 29 return springProcessEngineConfiguration -> springProcessEngineConfiguration.setSqlSessionFactory(sqlSessionFactory);
27 30 }
28 31  
  32 + @Bean
  33 + public FilterRegistrationBean<ActivitiWebFilter> activitiWebFilter() {
  34 + FilterRegistrationBean<ActivitiWebFilter> registrationBean = new FilterRegistrationBean<>();
  35 + registrationBean.setFilter(new ActivitiWebFilter());
  36 + registrationBean.setOrder(WebFilterOrderEnum.ACTIVITI_FILTER);
  37 + return registrationBean;
  38 + }
  39 +
29 40 }
... ...
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/core/util/ActivitiUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.activiti.core.util;
  2 +
  3 +import org.activiti.engine.impl.identity.Authentication;
  4 +
  5 +/**
  6 + * Activiti 工具类
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +public class ActivitiUtils {
  11 +
  12 + public static void setAuthenticatedUserId(Long userId) {
  13 + Authentication.setAuthenticatedUserId(String.valueOf(userId));
  14 + }
  15 +
  16 + public static void clearAuthenticatedUserId() {
  17 + Authentication.setAuthenticatedUserId(null);
  18 + }
  19 +
  20 +}
... ...
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/core/web/ActivitiWebFilter.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.activiti.core.web;
  2 +
  3 +import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils;
  4 +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
  5 +import org.springframework.web.filter.OncePerRequestFilter;
  6 +
  7 +import javax.servlet.FilterChain;
  8 +import javax.servlet.ServletException;
  9 +import javax.servlet.http.HttpServletRequest;
  10 +import javax.servlet.http.HttpServletResponse;
  11 +import java.io.IOException;
  12 +
  13 +/**
  14 + * Activiti Web 过滤器,将 userId 设置到 {@link org.activiti.engine.impl.identity.Authentication} 中
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +public class ActivitiWebFilter extends OncePerRequestFilter {
  19 +
  20 + @Override
  21 + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
  22 + throws ServletException, IOException {
  23 + try {
  24 + // 设置工作流的用户
  25 + Long userId = SecurityFrameworkUtils.getLoginUserId();
  26 + if (userId != null) {
  27 + ActivitiUtils.setAuthenticatedUserId(userId);
  28 + }
  29 + // 过滤
  30 + chain.doFilter(request, response);
  31 + } finally {
  32 + // 清理
  33 + ActivitiUtils.clearAuthenticatedUserId();
  34 + }
  35 + }
  36 +
  37 +}
... ...
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java
... ... @@ -98,15 +98,6 @@ public class SecurityFrameworkUtils {
98 98 // 原因是,Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息
99 99 WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
100 100 WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType());
101   -// // TODO @jason:使用 userId 会不会更合适哈?
102   -// // TODO @芋艿:activiti 需要使用 ttl 上下文
103   -// // TODO @jason:清理问题
104   -// if (Objects.equals(UserTypeEnum.ADMIN.getValue(), loginUser.getUserType())) {
105   -// org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername());
106   -// }
107   -// // TODO @芋道源码 该值被赋值给 user task 中assignee , username 显示更直白一点
108   -// // TODO @jason:有办法设置 userId,然后 activiti 有地方读取到 username 么?毕竟 username 只是 User 的登陆账号,并不能绝对像 userId 代表一个用户
109   -// org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername());
110 101 }
111 102  
112 103 }
... ...