mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-02-01 01:50:04 +08:00
1. 新增流程新建的接口
This commit is contained in:
parent
bcdc117e59
commit
2607f13abe
@ -0,0 +1,13 @@
|
|||||||
|
### 请求 /login 接口 => 成功
|
||||||
|
POST {{baseUrl}}/bpm/process-instance/create
|
||||||
|
Content-Type: application/json
|
||||||
|
tenant-id: 1
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"processDefinitionId": "leave:7:20ada39c-6c95-11ec-88b1-cacd34981f8e",
|
||||||
|
"variables": {
|
||||||
|
"a": 1,
|
||||||
|
"b": "2"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
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 = "流程实例") // 流程实例,通过流程定义创建的一次“申请”
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/bpm/process-instance")
|
||||||
|
@Validated
|
||||||
|
public class BpmProcessInstanceController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@ApiOperation("新建流程实例")
|
||||||
|
public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) {
|
||||||
|
return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ApiModel("流程实例的创建 Request VO")
|
||||||
|
@Data
|
||||||
|
//@EqualsAndHashCode(callSuper = true)
|
||||||
|
//@ToString(callSuper = true)
|
||||||
|
public class BpmProcessInstanceCreateReqVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "流程定义的编号", required = true, example = "1024")
|
||||||
|
@NotEmpty(message = "流程定义编号不能为空")
|
||||||
|
private String processDefinitionId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "变量实例")
|
||||||
|
private Map<String, Object> variables;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
|
||||||
|
public class BpmProcessInstanceMyPageReqVO extends PageParam {
|
||||||
|
}
|
@ -31,9 +31,13 @@ public interface BpmErrorCodeConstants {
|
|||||||
ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
|
ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图");
|
||||||
ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1009003001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图");
|
ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1009003001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图");
|
||||||
ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1009003002, "流程定义不存在");
|
ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1009003002, "流程定义不存在");
|
||||||
|
ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003002, "流程定义处于挂起状态");
|
||||||
|
|
||||||
// ========== 动态表单模块 1-009-004-000 ==========
|
// ========== 流程实例 1-009-004-000 ==========
|
||||||
ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009004000, "动态表单不存在");
|
|
||||||
ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009004000, "表单项({}) 和 ({}) 使用了相同的字段名({})");
|
|
||||||
|
// ========== 动态表单模块 1-009-010-000 ==========
|
||||||
|
ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在");
|
||||||
|
ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009010000, "表单项({}) 和 ({}) 使用了相同的字段名({})");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.adminserver.modules.bpm.service.task;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程实例 Service 接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface BpmProcessInstanceService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建流程实例
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 实例的编号
|
||||||
|
*/
|
||||||
|
String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||||
|
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
|
||||||
|
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.activiti.engine.HistoryService;
|
||||||
|
import org.activiti.engine.RepositoryService;
|
||||||
|
import org.activiti.engine.RuntimeService;
|
||||||
|
import org.activiti.engine.TaskService;
|
||||||
|
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;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_IS_SUSPENDED;
|
||||||
|
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS;
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程实例 Service 实现类
|
||||||
|
*
|
||||||
|
* ProcessDefinition & ProcessInstance & Execution & Task 的关系:
|
||||||
|
* 1. https://blog.csdn.net/bobozai86/article/details/105210414
|
||||||
|
*
|
||||||
|
* HistoricProcessInstance & ProcessInstance 的关系:
|
||||||
|
* 1.https://my.oschina.net/843294669/blog/719024
|
||||||
|
* 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
@Slf4j
|
||||||
|
public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RepositoryService repositoryService;
|
||||||
|
@Resource
|
||||||
|
private RuntimeService runtimeService;
|
||||||
|
@Resource
|
||||||
|
private TaskService taskService;
|
||||||
|
@Resource
|
||||||
|
private HistoryService historyService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysUserService userService;
|
||||||
|
@Resource
|
||||||
|
private BpmProcessDefinitionService processDefinitionService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createProcessInstance(Long userId, BpmProcessInstanceCreateReqVO createReqVO) {
|
||||||
|
// 校验流程定义
|
||||||
|
ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId());
|
||||||
|
if (definition == null) {
|
||||||
|
throw exception(PROCESS_DEFINITION_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
if (definition.isSuspended()) {
|
||||||
|
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 芋艿:在思考下
|
||||||
|
Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult();
|
||||||
|
if (task != null) {
|
||||||
|
SysUserDO user = userService.getUser(userId);
|
||||||
|
Assert.notNull(user, "用户({})不存在", userId);
|
||||||
|
String type = "normal";
|
||||||
|
taskService.addComment(task.getId(), instance.getProcessInstanceId(), type,
|
||||||
|
String.format("%s 发起流程申请", user.getNickname()));
|
||||||
|
// TODO 芋艿:应该不用下面两个步骤
|
||||||
|
// taskService.setAssignee(task.getId(), String.valueOf(userId));
|
||||||
|
// taskService.complete(task.getId(), variables);
|
||||||
|
}
|
||||||
|
return instance.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getMyProcessInstancePage(Long userId) {
|
||||||
|
HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery()
|
||||||
|
.startedBy(String.valueOf(userId)) // 发起人是自己
|
||||||
|
.orderByProcessInstanceStartTime().desc(); // 按照发起时间倒序
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -107,6 +107,14 @@ public interface SysUserService {
|
|||||||
*/
|
*/
|
||||||
PageResult<SysUserDO> getUserPage(SysUserPageReqVO reqVO);
|
PageResult<SysUserDO> getUserPage(SysUserPageReqVO reqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得用户
|
||||||
|
*
|
||||||
|
* @param id 用户编号
|
||||||
|
* @return 用户
|
||||||
|
*/
|
||||||
|
SysUserDO getUser(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得用户列表
|
* 获得用户列表
|
||||||
*
|
*
|
||||||
|
@ -164,6 +164,11 @@ public class SysUserServiceImpl implements SysUserService {
|
|||||||
return userMapper.selectPage(reqVO, this.getDeptCondition(reqVO.getDeptId()));
|
return userMapper.selectPage(reqVO, this.getDeptCondition(reqVO.getDeptId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysUserDO getUser(Long id) {
|
||||||
|
return userMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<SysUserDO> getUsers(SysUserExportReqVO reqVO) {
|
public List<SysUserDO> getUsers(SysUserExportReqVO reqVO) {
|
||||||
return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId()));
|
return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId()));
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package cn.iocoder.yudao.framework.security.core.util;
|
package cn.iocoder.yudao.framework.security.core.util;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
|
||||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||||
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
@ -12,7 +11,6 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,15 +98,15 @@ public class SecurityFrameworkUtils {
|
|||||||
// 原因是,Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息
|
// 原因是,Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息
|
||||||
WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
|
WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
|
||||||
WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType());
|
WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType());
|
||||||
// TODO @jason:使用 userId 会不会更合适哈?
|
// // TODO @jason:使用 userId 会不会更合适哈?
|
||||||
// TODO @芋艿:activiti 需要使用 ttl 上下文
|
// // TODO @芋艿:activiti 需要使用 ttl 上下文
|
||||||
// TODO @jason:清理问题
|
// // TODO @jason:清理问题
|
||||||
if (Objects.equals(UserTypeEnum.ADMIN.getValue(), loginUser.getUserType())) {
|
// if (Objects.equals(UserTypeEnum.ADMIN.getValue(), loginUser.getUserType())) {
|
||||||
org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername());
|
// org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername());
|
||||||
}
|
// }
|
||||||
// TODO @芋道源码 该值被赋值给 user task 中assignee , username 显示更直白一点
|
// // TODO @芋道源码 该值被赋值给 user task 中assignee , username 显示更直白一点
|
||||||
// TODO @jason:有办法设置 userId,然后 activiti 有地方读取到 username 么?毕竟 username 只是 User 的登陆账号,并不能绝对像 userId 代表一个用户
|
// // TODO @jason:有办法设置 userId,然后 activiti 有地方读取到 username 么?毕竟 username 只是 User 的登陆账号,并不能绝对像 userId 代表一个用户
|
||||||
org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername());
|
// org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user