Procházet zdrojové kódy

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

jason před 1 rokem
rodič
revize
053e03d068

+ 2 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java

@@ -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 = "流程实例")

+ 11 - 10
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java

@@ -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());

+ 18 - 12
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java

@@ -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());
+        });
     }
+
 }

+ 3 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java

@@ -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;

+ 3 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java

@@ -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())),