Commit 2607f13abeb65f3ae7c2174ad3b9d8c4c0e362f7
1 parent
bcdc117e
1. 新增流程新建的接口
Showing
10 changed files
with
229 additions
and
14 deletions
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.http
0 → 100644
| 1 | +### 请求 /login 接口 => 成功 | ||
| 2 | +POST {{baseUrl}}/bpm/process-instance/create | ||
| 3 | +Content-Type: application/json | ||
| 4 | +tenant-id: 1 | ||
| 5 | +Authorization: Bearer {{token}} | ||
| 6 | + | ||
| 7 | +{ | ||
| 8 | + "processDefinitionId": "leave:7:20ada39c-6c95-11ec-88b1-cacd34981f8e", | ||
| 9 | + "variables": { | ||
| 10 | + "a": 1, | ||
| 11 | + "b": "2" | ||
| 12 | + } | ||
| 13 | +} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/BpmProcessInstanceController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.task; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; | ||
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService; | ||
| 5 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 6 | +import io.swagger.annotations.Api; | ||
| 7 | +import io.swagger.annotations.ApiOperation; | ||
| 8 | +import org.springframework.validation.annotation.Validated; | ||
| 9 | +import org.springframework.web.bind.annotation.PostMapping; | ||
| 10 | +import org.springframework.web.bind.annotation.RequestBody; | ||
| 11 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 12 | +import org.springframework.web.bind.annotation.RestController; | ||
| 13 | + | ||
| 14 | +import javax.annotation.Resource; | ||
| 15 | +import javax.validation.Valid; | ||
| 16 | + | ||
| 17 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 18 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||
| 19 | + | ||
| 20 | +@Api(tags = "流程实例") // 流程实例,通过流程定义创建的一次“申请” | ||
| 21 | +@RestController | ||
| 22 | +@RequestMapping("/bpm/process-instance") | ||
| 23 | +@Validated | ||
| 24 | +public class BpmProcessInstanceController { | ||
| 25 | + | ||
| 26 | + @Resource | ||
| 27 | + private BpmProcessInstanceService processInstanceService; | ||
| 28 | + | ||
| 29 | + @PostMapping("/create") | ||
| 30 | + @ApiOperation("新建流程实例") | ||
| 31 | + public CommonResult<String> createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) { | ||
| 32 | + return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO)); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | +} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceCreateReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance; | ||
| 2 | + | ||
| 3 | +import io.swagger.annotations.ApiModel; | ||
| 4 | +import io.swagger.annotations.ApiModelProperty; | ||
| 5 | +import lombok.Data; | ||
| 6 | + | ||
| 7 | +import javax.validation.constraints.NotEmpty; | ||
| 8 | +import java.util.Map; | ||
| 9 | + | ||
| 10 | +@ApiModel("流程实例的创建 Request VO") | ||
| 11 | +@Data | ||
| 12 | +//@EqualsAndHashCode(callSuper = true) | ||
| 13 | +//@ToString(callSuper = true) | ||
| 14 | +public class BpmProcessInstanceCreateReqVO { | ||
| 15 | + | ||
| 16 | + @ApiModelProperty(value = "流程定义的编号", required = true, example = "1024") | ||
| 17 | + @NotEmpty(message = "流程定义编号不能为空") | ||
| 18 | + private String processDefinitionId; | ||
| 19 | + | ||
| 20 | + @ApiModelProperty(value = "变量实例") | ||
| 21 | + private Map<String, Object> variables; | ||
| 22 | + | ||
| 23 | +} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/instance/BpmProcessInstanceMyPageReqVO.java
0 → 100644
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/enums/BpmErrorCodeConstants.java
| @@ -31,9 +31,13 @@ public interface BpmErrorCodeConstants { | @@ -31,9 +31,13 @@ public interface BpmErrorCodeConstants { | ||
| 31 | ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图"); | 31 | ErrorCode PROCESS_DEFINITION_KEY_NOT_MATCH = new ErrorCode(1009003000, "流程定义的标识期望是({}),当前是({}),请修改 BPMN 流程图"); |
| 32 | ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1009003001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图"); | 32 | ErrorCode PROCESS_DEFINITION_NAME_NOT_MATCH = new ErrorCode(1009003001, "流程定义的名字期望是({}),当前是({}),请修改 BPMN 流程图"); |
| 33 | ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1009003002, "流程定义不存在"); | 33 | ErrorCode PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1009003002, "流程定义不存在"); |
| 34 | + ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003002, "流程定义处于挂起状态"); | ||
| 34 | 35 | ||
| 35 | - // ========== 动态表单模块 1-009-004-000 ========== | ||
| 36 | - ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009004000, "动态表单不存在"); | ||
| 37 | - ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009004000, "表单项({}) 和 ({}) 使用了相同的字段名({})"); | 36 | + // ========== 流程实例 1-009-004-000 ========== |
| 37 | + | ||
| 38 | + | ||
| 39 | + // ========== 动态表单模块 1-009-010-000 ========== | ||
| 40 | + ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在"); | ||
| 41 | + ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1009010000, "表单项({}) 和 ({}) 使用了相同的字段名({})"); | ||
| 38 | 42 | ||
| 39 | } | 43 | } |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmProcessInstanceService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.service.task; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; | ||
| 4 | + | ||
| 5 | +import javax.validation.Valid; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 流程实例 Service 接口 | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +public interface BpmProcessInstanceService { | ||
| 13 | + | ||
| 14 | + /** | ||
| 15 | + * 创建流程实例 | ||
| 16 | + * | ||
| 17 | + * @param userId 用户编号 | ||
| 18 | + * @param createReqVO 创建信息 | ||
| 19 | + * @return 实例的编号 | ||
| 20 | + */ | ||
| 21 | + String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO); | ||
| 22 | + | ||
| 23 | +} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmProcessInstanceServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.lang.Assert; | ||
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; | ||
| 5 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; | ||
| 6 | +import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService; | ||
| 7 | +import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; | ||
| 8 | +import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; | ||
| 9 | +import lombok.extern.slf4j.Slf4j; | ||
| 10 | +import org.activiti.engine.HistoryService; | ||
| 11 | +import org.activiti.engine.RepositoryService; | ||
| 12 | +import org.activiti.engine.RuntimeService; | ||
| 13 | +import org.activiti.engine.TaskService; | ||
| 14 | +import org.activiti.engine.history.HistoricProcessInstanceQuery; | ||
| 15 | +import org.activiti.engine.impl.identity.Authentication; | ||
| 16 | +import org.activiti.engine.repository.ProcessDefinition; | ||
| 17 | +import org.activiti.engine.runtime.ProcessInstance; | ||
| 18 | +import org.activiti.engine.task.Task; | ||
| 19 | +import org.springframework.stereotype.Service; | ||
| 20 | +import org.springframework.validation.annotation.Validated; | ||
| 21 | + | ||
| 22 | +import javax.annotation.Resource; | ||
| 23 | +import java.util.Map; | ||
| 24 | + | ||
| 25 | +import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_IS_SUSPENDED; | ||
| 26 | +import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS; | ||
| 27 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * 流程实例 Service 实现类 | ||
| 31 | + * | ||
| 32 | + * ProcessDefinition & ProcessInstance & Execution & Task 的关系: | ||
| 33 | + * 1. https://blog.csdn.net/bobozai86/article/details/105210414 | ||
| 34 | + * | ||
| 35 | + * HistoricProcessInstance & ProcessInstance 的关系: | ||
| 36 | + * 1.https://my.oschina.net/843294669/blog/719024 | ||
| 37 | + * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 | ||
| 38 | + * | ||
| 39 | + * @author 芋道源码 | ||
| 40 | + */ | ||
| 41 | +@Service | ||
| 42 | +@Validated | ||
| 43 | +@Slf4j | ||
| 44 | +public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { | ||
| 45 | + | ||
| 46 | + @Resource | ||
| 47 | + private RepositoryService repositoryService; | ||
| 48 | + @Resource | ||
| 49 | + private RuntimeService runtimeService; | ||
| 50 | + @Resource | ||
| 51 | + private TaskService taskService; | ||
| 52 | + @Resource | ||
| 53 | + private HistoryService historyService; | ||
| 54 | + | ||
| 55 | + @Resource | ||
| 56 | + private SysUserService userService; | ||
| 57 | + @Resource | ||
| 58 | + private BpmProcessDefinitionService processDefinitionService; | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public String createProcessInstance(Long userId, BpmProcessInstanceCreateReqVO createReqVO) { | ||
| 62 | + // 校验流程定义 | ||
| 63 | + ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); | ||
| 64 | + if (definition == null) { | ||
| 65 | + throw exception(PROCESS_DEFINITION_NOT_EXISTS); | ||
| 66 | + } | ||
| 67 | + if (definition.isSuspended()) { | ||
| 68 | + throw exception(PROCESS_DEFINITION_IS_SUSPENDED); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + // 设置流程发起人 | ||
| 72 | + Authentication.setAuthenticatedUserId(String.valueOf(userId)); | ||
| 73 | + | ||
| 74 | + // 创建流程实例 | ||
| 75 | + Map<String, Object> variables = createReqVO.getVariables(); | ||
| 76 | + variables.put("INITIATOR", userId); // TODO 芋艿:初始化人员 | ||
| 77 | + ProcessInstance instance = runtimeService.startProcessInstanceById(createReqVO.getProcessDefinitionId(), variables); | ||
| 78 | + | ||
| 79 | + // 添加初始的评论 TODO 芋艿:在思考下 | ||
| 80 | + Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult(); | ||
| 81 | + if (task != null) { | ||
| 82 | + SysUserDO user = userService.getUser(userId); | ||
| 83 | + Assert.notNull(user, "用户({})不存在", userId); | ||
| 84 | + String type = "normal"; | ||
| 85 | + taskService.addComment(task.getId(), instance.getProcessInstanceId(), type, | ||
| 86 | + String.format("%s 发起流程申请", user.getNickname())); | ||
| 87 | + // TODO 芋艿:应该不用下面两个步骤 | ||
| 88 | +// taskService.setAssignee(task.getId(), String.valueOf(userId)); | ||
| 89 | +// taskService.complete(task.getId(), variables); | ||
| 90 | + } | ||
| 91 | + return instance.getId(); | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + public void getMyProcessInstancePage(Long userId) { | ||
| 95 | + HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery() | ||
| 96 | + .startedBy(String.valueOf(userId)) // 发起人是自己 | ||
| 97 | + .orderByProcessInstanceStartTime().desc(); // 按照发起时间倒序 | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | +} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserService.java
| @@ -108,6 +108,14 @@ public interface SysUserService { | @@ -108,6 +108,14 @@ public interface SysUserService { | ||
| 108 | PageResult<SysUserDO> getUserPage(SysUserPageReqVO reqVO); | 108 | PageResult<SysUserDO> getUserPage(SysUserPageReqVO reqVO); |
| 109 | 109 | ||
| 110 | /** | 110 | /** |
| 111 | + * 获得用户 | ||
| 112 | + * | ||
| 113 | + * @param id 用户编号 | ||
| 114 | + * @return 用户 | ||
| 115 | + */ | ||
| 116 | + SysUserDO getUser(Long id); | ||
| 117 | + | ||
| 118 | + /** | ||
| 111 | * 获得用户列表 | 119 | * 获得用户列表 |
| 112 | * | 120 | * |
| 113 | * @param reqVO 列表请求 | 121 | * @param reqVO 列表请求 |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java
| @@ -165,6 +165,11 @@ public class SysUserServiceImpl implements SysUserService { | @@ -165,6 +165,11 @@ public class SysUserServiceImpl implements SysUserService { | ||
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | @Override | 167 | @Override |
| 168 | + public SysUserDO getUser(Long id) { | ||
| 169 | + return userMapper.selectById(id); | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + @Override | ||
| 168 | public List<SysUserDO> getUsers(SysUserExportReqVO reqVO) { | 173 | public List<SysUserDO> getUsers(SysUserExportReqVO reqVO) { |
| 169 | return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId())); | 174 | return userMapper.selectList(reqVO, this.getDeptCondition(reqVO.getDeptId())); |
| 170 | } | 175 | } |
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/util/SecurityFrameworkUtils.java
| 1 | package cn.iocoder.yudao.framework.security.core.util; | 1 | package cn.iocoder.yudao.framework.security.core.util; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||
| 4 | import cn.iocoder.yudao.framework.security.core.LoginUser; | 3 | import cn.iocoder.yudao.framework.security.core.LoginUser; |
| 5 | import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; | 4 | import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; |
| 6 | import org.springframework.lang.Nullable; | 5 | import org.springframework.lang.Nullable; |
| @@ -12,7 +11,6 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS | @@ -12,7 +11,6 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS | ||
| 12 | import org.springframework.util.StringUtils; | 11 | import org.springframework.util.StringUtils; |
| 13 | 12 | ||
| 14 | import javax.servlet.http.HttpServletRequest; | 13 | import javax.servlet.http.HttpServletRequest; |
| 15 | -import java.util.Objects; | ||
| 16 | import java.util.Set; | 14 | import java.util.Set; |
| 17 | 15 | ||
| 18 | /** | 16 | /** |
| @@ -100,15 +98,15 @@ public class SecurityFrameworkUtils { | @@ -100,15 +98,15 @@ public class SecurityFrameworkUtils { | ||
| 100 | // 原因是,Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息 | 98 | // 原因是,Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息 |
| 101 | WebFrameworkUtils.setLoginUserId(request, loginUser.getId()); | 99 | WebFrameworkUtils.setLoginUserId(request, loginUser.getId()); |
| 102 | WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType()); | 100 | WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType()); |
| 103 | - // TODO @jason:使用 userId 会不会更合适哈? | ||
| 104 | - // TODO @芋艿:activiti 需要使用 ttl 上下文 | ||
| 105 | - // TODO @jason:清理问题 | ||
| 106 | - if (Objects.equals(UserTypeEnum.ADMIN.getValue(), loginUser.getUserType())) { | ||
| 107 | - org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername()); | ||
| 108 | - } | ||
| 109 | - // TODO @芋道源码 该值被赋值给 user task 中assignee , username 显示更直白一点 | ||
| 110 | - // TODO @jason:有办法设置 userId,然后 activiti 有地方读取到 username 么?毕竟 username 只是 User 的登陆账号,并不能绝对像 userId 代表一个用户 | ||
| 111 | - org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(loginUser.getUsername()); | 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()); | ||
| 112 | } | 110 | } |
| 113 | 111 | ||
| 114 | } | 112 | } |