仿钉钉流程设计- 表单字段权限设置

This commit is contained in:
jason 2024-06-27 09:21:22 +08:00
parent 5519fdcd4c
commit 053e03d068
5 changed files with 37 additions and 27 deletions

View File

@ -67,6 +67,8 @@ public class BpmTaskRespVO {
private List<String> formFields;
@Schema(description = "提交的表单值", requiredMode = Schema.RequiredMode.REQUIRED)
private Map<String, Object> formVariables;
@Schema(description = "表单字段权限值")
private Map<String,String> fieldsPermission;
@Data
@Schema(description = "流程实例")

View File

@ -9,6 +9,8 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCreatedReqDTO;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
@ -86,7 +88,8 @@ public interface BpmTaskConvert {
BpmnModel bpmnModel) {
List<BpmTaskRespVO> taskVOList = CollectionUtils.convertList(taskList, task -> {
BpmTaskRespVO taskVO = BeanUtils.toBean(task, BpmTaskRespVO.class);
taskVO.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task));
Integer taskStatus = FlowableUtils.getTaskStatus(task);
taskVO.setStatus(taskStatus).setReason(FlowableUtils.getTaskReason(task));
// 流程实例
AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
@ -94,12 +97,6 @@ public interface BpmTaskConvert {
// 表单信息
BpmFormDO form = MapUtil.get(formMap, NumberUtils.parseLong(task.getFormKey()), BpmFormDO.class);
if (form != null) {
// 测试一下权限处理
// TODO @jason这里是不是还没实现完哈
// TODO @芋艿 测试了一下 暂时注释掉 前端不知道要怎样改 可能需要讨论一下如何改
// List<String> afterChangedFields = BpmnFormUtils.changeCreateFormFiledPermissionRule(form.getFields(),
// BpmnModelUtils.parseFormFieldsPermission(bpmnModel, task.getTaskDefinitionKey()));
taskVO.setFormId(form.getId()).setFormName(form.getName()).setFormConf(form.getConf())
.setFormFields(form.getFields()).setFormVariables(FlowableUtils.getTaskFormVariable(task));
}
@ -114,7 +111,11 @@ public interface BpmTaskConvert {
taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceRespVO.User.class));
findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
}
return taskVO;
if(BpmTaskStatusEnum.RUNNING.getStatus().equals(taskStatus)){
// 设置表单权限 TODO @芋艿 是不是还要加一个全局的权限 基于 processInstance 的权限
taskVO.setFieldsPermission(BpmnModelUtils.parseFormFieldsPermission(bpmnModel, task.getTaskDefinitionKey()));
}
return taskVO;
});
// 拼接父子关系
@ -159,12 +160,12 @@ public interface BpmTaskConvert {
/**
* 将父任务的属性拷贝到子任务加签任务
*
* <p>
* 为什么不使用 mapstruct 映射因为 TaskEntityImpl 还有很多其他属性这里我们只设置我们需要的
* 使用 mapstruct 会将里面嵌套的各个属性值都设置进去会出现意想不到的问题
*
* @param parentTask 父任务
* @param childTask 加签任务
* @param childTask 加签任务
*/
default void copyTo(TaskEntityImpl parentTask, TaskEntityImpl childTask) {
childTask.setName(parentTask.getName());

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService;
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
import com.google.common.collect.ImmutableSet;
@ -9,10 +11,12 @@ import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.task.api.Task;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Set;
/**
@ -55,18 +59,20 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
@Override
protected void activityCancelled(FlowableActivityCancelledEvent event) {
// TODO @jason如果用户主动取消可能需要考虑这个
// TODO @芋艿 如果在 rejectTask 处理了 这里又要查询一次感觉有点多余 主动取消是不是也要处理一下要不然有加签的任务也会报错
// @芋艿 这里是不是就可以不要了 取消的任务状态在rejectTask 里面做了 如果在 updateTaskStatusWhenCanceled 里面修改会报错
// List<HistoricActivityInstance> activityList = activityService.getHistoricActivityListByExecutionId(event.getExecutionId());
// if (CollUtil.isEmpty(activityList)) {
// log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]", event.getExecutionId());
// return;
// }
// // 遍历处理
// activityList.forEach(activity -> {
// if (StrUtil.isEmpty(activity.getTaskId())) {
// return;
// }
// taskService.updateTaskStatusWhenCanceled(activity.getTaskId());
// });
List<HistoricActivityInstance> activityList = activityService.getHistoricActivityListByExecutionId(event.getExecutionId());
if (CollUtil.isEmpty(activityList)) {
log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]", event.getExecutionId());
return;
}
// 遍历处理
activityList.forEach(activity -> {
if (StrUtil.isEmpty(activity.getTaskId())) {
return;
}
taskService.updateTaskStatusWhenCanceled(activity.getTaskId());
});
}
}

View File

@ -60,19 +60,18 @@ public class BpmnModelUtils {
return element != null ? element.getElementText() : null;
}
// TODO @jason貌似这个没地方调用 @芋艿 BpmTaskConvert里面暂时注释掉了
public static Map<String, Integer> parseFormFieldsPermission(BpmnModel bpmnModel, String flowElementId) {
public static Map<String, String> parseFormFieldsPermission(BpmnModel bpmnModel, String flowElementId) {
FlowElement flowElement = getFlowElementById(bpmnModel, flowElementId);
if (flowElement == null) {
return null;
}
Map<String, Integer> fieldsPermission = MapUtil.newHashMap();
Map<String, String> fieldsPermission = MapUtil.newHashMap();
List<ExtensionElement> extensionElements = flowElement.getExtensionElements().get(FORM_FIELD_PERMISSION_ELEMENT);
extensionElements.forEach(element -> {
String field = element.getAttributeValue(FLOWABLE_EXTENSIONS_NAMESPACE, FORM_FIELD_PERMISSION_ELEMENT_FIELD_ATTRIBUTE);
String permission = element.getAttributeValue(FLOWABLE_EXTENSIONS_NAMESPACE, FORM_FIELD_PERMISSION_ELEMENT_PERMISSION_ATTRIBUTE);
if (StrUtil.isNotEmpty(field) && StrUtil.isNotEmpty(permission)) {
fieldsPermission.put(field, Integer.parseInt(permission));
fieldsPermission.put(field, permission);
}
});
return fieldsPermission;

View File

@ -213,6 +213,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
// 其中variables 是存储动态表单到 local 任务级别过滤一下避免 ProcessInstance 系统级的变量被占用
if (CollUtil.isNotEmpty(reqVO.getVariables())) {
Map<String, Object> variables = FlowableUtils.filterTaskFormVariable(reqVO.getVariables());
// 修改表单的值需要存储到 ProcessInstance 变量
runtimeService.setVariables(task.getProcessInstanceId(), variables);
taskService.complete(task.getId(), variables, true);
} else {
taskService.complete(task.getId());
@ -371,7 +373,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
}
// 4.2.1 更新其它正在运行的任务状态为取消需要过滤掉当前任务和被加签的任务
// TODO @jason如果过滤掉被加签的任务这些任务被对应的审批人看到是啥状态哈
// TODO @jason如果过滤掉被加签的任务这些任务被对应的审批人看到是啥状态哈 @芋艿 为不通过状态
List<Task> taskList = getRunningTaskListByProcessInstanceId(instance.getProcessInstanceId(), false, null, null);
updateTaskStatusWhenCanceled(
CollectionUtils.filterList(taskList, item -> !item.getId().equals(task.getId()) && !item.getId().equals(task.getParentTaskId())),