parent
e43039b0c6
commit
4d7ee1769f
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue