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