mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-02-03 04:04:58 +08:00
Merge remote-tracking branch 'origin/feature/bpm' into feature/bpm
# Conflicts: # sql/mysql/bpm_update.sql # yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
This commit is contained in:
commit
c05f9fe98e
14
sql/mysql/bpm_update.sql
Normal file
14
sql/mysql/bpm_update.sql
Normal file
@ -0,0 +1,14 @@
|
||||
-- ----------------------------
|
||||
-- 流程抄送表新加流程活动编号
|
||||
-- ----------------------------
|
||||
ALTER TABLE `bpm_process_instance_copy`
|
||||
ADD COLUMN `activity_id` varchar(64) NULL COMMENT '流程活动编号' AFTER `category`,
|
||||
MODIFY COLUMN `task_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '任务编号' AFTER `category`;
|
||||
|
||||
ALTER TABLE `bpm_process_definition_info`
|
||||
ADD COLUMN `model_type` tinyint NOT NULL DEFAULT 10 COMMENT '流程模型的类型' AFTER `model_id`,
|
||||
ADD COLUMN `simple_model` json NULL COMMENT 'SIMPLE 设计器模型数据' AFTER `form_custom_view_path`,
|
||||
ADD COLUMN `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见' AFTER `simple_model`;
|
||||
|
||||
ALTER TABLE `bpm_process_instance_copy`
|
||||
ADD COLUMN `reason` varchar(256) NULL COMMENT '抄送意见' AFTER `task_name`;
|
@ -210,6 +210,14 @@ public class BpmTaskController {
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/copy")
|
||||
@Operation(summary = "抄送任务")
|
||||
@PreAuthorize("@ss.hasPermission('bpm:task:update')")
|
||||
public CommonResult<Boolean> copyTask(@Valid @RequestBody BpmTaskCopyReqVO reqVO) {
|
||||
taskService.copyTask(getLoginUserId(), reqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-parent-task-id")
|
||||
@Operation(summary = "获得指定父级任务的子任务列表") // 目前用于,减签的时候,获得子任务列表
|
||||
@Parameter(name = "parentTaskId", description = "父级任务编号", required = true)
|
||||
|
@ -19,9 +19,9 @@ public class BpmProcessInstanceCopyRespVO {
|
||||
|
||||
@Schema(description = "流程实例编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "A233")
|
||||
private String processInstanceId;
|
||||
@Schema(description = "流程实例的名称")
|
||||
@Schema(description = "流程实例的名称",requiredMode = Schema.RequiredMode.REQUIRED, example = "测试")
|
||||
private String processInstanceName;
|
||||
@Schema(description = "流程实例的发起时间")
|
||||
@Schema(description = "流程实例的发起时间",requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime processInstanceStartTime;
|
||||
|
||||
@Schema(description = "抄送的节点的活动编号")
|
||||
@ -31,12 +31,14 @@ public class BpmProcessInstanceCopyRespVO {
|
||||
@Schema(description = "发起抄送的任务名称")
|
||||
private String taskName;
|
||||
|
||||
@Schema(description = "抄送人")
|
||||
@Schema(description = "抄送人", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private String creator;
|
||||
@Schema(description = "抄送人昵称")
|
||||
private String creatorName;
|
||||
@Schema(description = "抄送人意见")
|
||||
private String reason;
|
||||
|
||||
@Schema(description = "抄送时间")
|
||||
@Schema(description = "抄送时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@ -42,24 +43,7 @@ public class BpmApprovalDetailRespVO {
|
||||
private List<ApprovalTaskInfo> tasks;
|
||||
|
||||
@Schema(description = "候选人用户列表")
|
||||
// TODO @jason:candidateUserList => candidateUsers,保持和 tasks 的命名风格一致哈
|
||||
private List<User> candidateUserList; // 用于未运行任务节点
|
||||
|
||||
}
|
||||
|
||||
// TODO @jason:可以替换成 UserSimpleBaseVO。简化下
|
||||
@Schema(description = "用户信息")
|
||||
@Data
|
||||
public static class User {
|
||||
|
||||
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "用户头像", example = "https://www.iocoder.cn/1.png")
|
||||
private String avatar;
|
||||
private List<UserSimpleBaseVO> candidateUsers; // 用于未运行任务节点
|
||||
|
||||
}
|
||||
|
||||
@ -71,10 +55,10 @@ public class BpmApprovalDetailRespVO {
|
||||
private String id;
|
||||
|
||||
@Schema(description = "任务所属人", example = "1024")
|
||||
private User ownerUser;
|
||||
private UserSimpleBaseVO ownerUser;
|
||||
|
||||
@Schema(description = "任务分配人", example = "2048")
|
||||
private User assigneeUser;
|
||||
private UserSimpleBaseVO assigneeUser;
|
||||
|
||||
@Schema(description = "任务状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status; // 参见 BpmTaskStatusEnum 枚举
|
||||
|
@ -66,6 +66,8 @@ public class BpmProcessInstanceRespVO {
|
||||
private Long id;
|
||||
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
private String nickname;
|
||||
@Schema(description = "用户头像", example = "https://www.iocoder.cn/1.png")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long deptId;
|
||||
|
@ -19,7 +19,7 @@ public class BpmTaskApproveReqVO {
|
||||
@NotEmpty(message = "审批意见不能为空")
|
||||
private String reason;
|
||||
|
||||
@Schema(description = "抄送的用户编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2")
|
||||
@Schema(description = "抄送的用户编号数组", example = "1,2")
|
||||
private Collection<Long> copyUserIds;
|
||||
|
||||
@Schema(description = "变量实例(动态表单)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
|
@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@Schema(description = "管理后台 - 抄送流程任务的 Request VO")
|
||||
@Data
|
||||
public class BpmTaskCopyReqVO {
|
||||
|
||||
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotEmpty(message = "任务编号不能为空")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "抄送的用户编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1,2]")
|
||||
@NotEmpty(message = "抄送用户不能为空")
|
||||
private Collection<Long> copyUserIds;
|
||||
|
||||
@Schema(description = "抄送意见", example = "帮忙看看!")
|
||||
private String reason;
|
||||
}
|
@ -74,4 +74,9 @@ public class BpmProcessInstanceCopyDO extends BaseDO {
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 抄送意见
|
||||
*/
|
||||
private String reason;
|
||||
|
||||
}
|
||||
|
@ -102,8 +102,7 @@ public class BpmTaskCandidateInvoker {
|
||||
String param = BpmnModelUtils.parseCandidateParam(execution.getCurrentFlowElement());
|
||||
// 1.1 计算任务的候选人
|
||||
Set<Long> userIds = getCandidateStrategy(strategy).calculateUsers(execution, param);
|
||||
removeDisableUsers(userIds);
|
||||
// 1.2 移除被禁用的用户
|
||||
// 1.2 移除被禁用的用户 TODO @芋艿 在 calculateUsers 方法中默认已经移除了被禁用的用户, 这里还需要移除被禁用的用户吗?
|
||||
removeDisableUsers(userIds);
|
||||
|
||||
// 2. 候选人为空时,根据“审批人为空”的配置补充
|
||||
|
@ -59,6 +59,8 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends BpmTaskCan
|
||||
}
|
||||
Set<Long> users = getMultiLevelDeptLeaderIds(toList(dept.getId()), Integer.valueOf(param)); // 参数是部门的层级
|
||||
// TODO @jason:这里 removeDisableUsers 的原因是啥呀?
|
||||
// TODO @芋艿 calculateUsers(execution, param) calculateUsers(startUserId, processInstance, activityId, param) 现在这两个方法, 默认都移除了被禁用的用户
|
||||
// TODO @芋艿 因为被禁用的用户是不能审批任务。 在这里移除是不是好一点。 代码可以重用。
|
||||
removeDisableUsers(users);
|
||||
return users;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import static cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmCo
|
||||
|
||||
/**
|
||||
* 处理抄送用户的 {@link JavaDelegate} 的实现类
|
||||
*
|
||||
* <p>
|
||||
* 目前只有快搭模式的【抄送节点】使用
|
||||
*
|
||||
* @author jason
|
||||
@ -40,7 +40,7 @@ public class BpmCopyTaskDelegate implements JavaDelegate {
|
||||
}
|
||||
// 2. 执行抄送
|
||||
FlowElement currentFlowElement = execution.getCurrentFlowElement();
|
||||
processInstanceCopyService.createProcessInstanceCopy(userIds, execution.getProcessInstanceId(),
|
||||
processInstanceCopyService.createProcessInstanceCopy(userIds, null, execution.getProcessInstanceId(),
|
||||
currentFlowElement.getId(), null, currentFlowElement.getName());
|
||||
}
|
||||
|
||||
|
@ -18,21 +18,23 @@ public interface BpmProcessInstanceCopyService {
|
||||
* 流程实例的抄送
|
||||
*
|
||||
* @param userIds 抄送的用户编号
|
||||
* @param reason 抄送意见
|
||||
* @param taskId 流程任务编号
|
||||
*/
|
||||
void createProcessInstanceCopy(Collection<Long> userIds, String taskId);
|
||||
void createProcessInstanceCopy(Collection<Long> userIds, String reason, String taskId);
|
||||
|
||||
/**
|
||||
* 流程实例的抄送
|
||||
*
|
||||
* @param userIds 抄送的用户编号
|
||||
* @param reason 抄送意见
|
||||
* @param processInstanceId 流程编号
|
||||
* @param activityId 流程活动编号 id (对应 BPMN XML 节点 Id)
|
||||
* // TODO 芋艿这个 taskId 是不是可以不要了
|
||||
* @param taskId 任务编号
|
||||
* @param taskName 任务名称
|
||||
*/
|
||||
void createProcessInstanceCopy(Collection<Long> userIds, String processInstanceId, String activityId, String taskId, String taskName);
|
||||
void createProcessInstanceCopy(Collection<Long> userIds, String reason, String processInstanceId, String activityId,
|
||||
String taskId, String taskName);
|
||||
|
||||
/**
|
||||
* 获得抄送的流程的分页
|
||||
@ -43,14 +45,5 @@ public interface BpmProcessInstanceCopyService {
|
||||
*/
|
||||
PageResult<BpmProcessInstanceCopyDO> getProcessInstanceCopyPage(Long userId,
|
||||
BpmProcessInstanceCopyPageReqVO pageReqVO);
|
||||
// TODO @芋艿:重点在 review 下
|
||||
/**
|
||||
* 通过流程实例和流程活动编号获取抄送人的 Id
|
||||
*
|
||||
* @param processInstanceId 流程实例 Id
|
||||
* @param activityId 流程活动编号 Id
|
||||
* @return 抄送人 Ids
|
||||
*/
|
||||
Set<Long> getCopyUserIds(String processInstanceId, String activityId);
|
||||
|
||||
}
|
||||
|
@ -49,17 +49,18 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy
|
||||
private BpmProcessDefinitionService processDefinitionService;
|
||||
|
||||
@Override
|
||||
public void createProcessInstanceCopy(Collection<Long> userIds, String taskId) {
|
||||
public void createProcessInstanceCopy(Collection<Long> userIds, String reason, String taskId) {
|
||||
Task task = taskService.getTask(taskId);
|
||||
if (ObjectUtil.isNull(task)) {
|
||||
throw exception(ErrorCodeConstants.TASK_NOT_EXISTS);
|
||||
}
|
||||
String processInstanceId = task.getProcessInstanceId();
|
||||
createProcessInstanceCopy(userIds, processInstanceId, task.getTaskDefinitionKey(), task.getId(), task.getName());
|
||||
createProcessInstanceCopy(userIds, reason, processInstanceId, task.getTaskDefinitionKey(), task.getId(), task.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createProcessInstanceCopy(Collection<Long> userIds, String processInstanceId, String activityId, String taskId, String taskName) {
|
||||
public void createProcessInstanceCopy(Collection<Long> userIds, String reason, String processInstanceId, String activityId,
|
||||
String taskId, String taskName) {
|
||||
// 1.1 校验流程实例存在
|
||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId);
|
||||
if (processInstance == null) {
|
||||
@ -74,7 +75,7 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy
|
||||
|
||||
// 2. 创建抄送流程
|
||||
List<BpmProcessInstanceCopyDO> copyList = convertList(userIds, userId -> new BpmProcessInstanceCopyDO()
|
||||
.setUserId(userId).setStartUserId(Long.valueOf(processInstance.getStartUserId()))
|
||||
.setUserId(userId).setReason(reason).setStartUserId(Long.valueOf(processInstance.getStartUserId()))
|
||||
.setProcessInstanceId(processInstanceId).setProcessInstanceName(processInstance.getName())
|
||||
.setCategory(processDefinition.getCategory()).setActivityId(activityId)
|
||||
.setTaskId(taskId).setTaskName(taskName));
|
||||
@ -87,10 +88,4 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy
|
||||
return processInstanceCopyMapper.selectPage(userId, pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getCopyUserIds(String processInstanceId, String activityId) {
|
||||
return CollectionUtils.convertSet(processInstanceCopyMapper.selectListByProcessInstanceIdAndActivityId(processInstanceId, activityId),
|
||||
BpmProcessInstanceCopyDO::getUserId);
|
||||
}
|
||||
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -202,6 +202,14 @@ public interface BpmTaskService {
|
||||
*/
|
||||
void deleteSignTask(Long userId, BpmTaskSignDeleteReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 抄送任务
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param reqVO 通过请求
|
||||
*/
|
||||
void copyTask(Long userId, @Valid BpmTaskCopyReqVO reqVO);
|
||||
|
||||
// ========== Event 事件相关方法 ==========
|
||||
|
||||
/**
|
||||
|
@ -354,7 +354,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
|
||||
// 2. 抄送用户
|
||||
if (CollUtil.isNotEmpty(reqVO.getCopyUserIds())) {
|
||||
processInstanceCopyService.createProcessInstanceCopy(reqVO.getCopyUserIds(), reqVO.getId());
|
||||
processInstanceCopyService.createProcessInstanceCopy(reqVO.getCopyUserIds(), null, reqVO.getId());
|
||||
}
|
||||
|
||||
// 情况一:被委派的任务,不调用 complete 去完成任务
|
||||
@ -868,6 +868,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
handleParentTaskIfSign(task.getParentTaskId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTask(Long userId, BpmTaskCopyReqVO reqVO) {
|
||||
processInstanceCopyService.createProcessInstanceCopy(reqVO.getCopyUserIds(), reqVO.getReason(), reqVO.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验任务是否能被减签
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user