Przeglądaj źródła

update 优化工作流权限按钮获取,若需要扩展更多按钮权限,只需在 sources 中新增对应的枚举类或字典类型

AprilWind 1 rok temu
rodzic
commit
5c9721cfac

+ 12 - 3
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ButtonPermission.java → ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ButtonPermissionVo.java

@@ -12,18 +12,18 @@ import java.io.Serializable;
  * @date 2025-02-28
  */
 @Data
-public class ButtonPermission implements Serializable {
+public class ButtonPermissionVo implements Serializable {
 
     @Serial
     private static final long serialVersionUID = 1L;
 
     /**
-     * 枚举路径
+     * 唯一编码
      */
     private String code;
 
     /**
-     * 按钮编码
+     * 选项值
      */
     private String value;
 
@@ -31,4 +31,13 @@ public class ButtonPermission implements Serializable {
      * 是否显示
      */
     private boolean show;
+
+    public ButtonPermissionVo() {
+    }
+
+    public ButtonPermissionVo(String code, boolean show) {
+        this.code = code;
+        this.show = show;
+    }
+
 }

+ 4 - 32
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowTaskVo.java

@@ -1,20 +1,16 @@
 package org.dromara.workflow.domain.vo;
 
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.json.JSONUtil;
 import lombok.Data;
-import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.translation.annotation.Translation;
 import org.dromara.common.translation.constant.TransConstant;
 import org.dromara.warm.flow.core.entity.User;
 import org.dromara.workflow.common.constant.FlowConstant;
-import org.dromara.workflow.common.enums.ButtonPermissionEnum;
 
 import java.io.Serial;
 import java.io.Serializable;
 import java.math.BigDecimal;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.Date;
+import java.util.List;
 
 /**
  * 任务视图
@@ -186,30 +182,6 @@ public class FlowTaskVo implements Serializable {
     /**
      * 按钮权限
      */
-    private List<ButtonPermission> buttonList;
-
-    public List<ButtonPermission> getButtonList(String ext) {
-        List<ButtonPermission> buttonPermissions = Arrays.stream(ButtonPermissionEnum.values())
-            .map(value -> {
-                ButtonPermission buttonPermission = new ButtonPermission();
-                buttonPermission.setCode(value.getValue());
-                buttonPermission.setShow(false);
-                return buttonPermission;
-            })
-            .collect(Collectors.toList());
-        if (StringUtils.isNotBlank(ext)) {
-            List<ButtonPermission> buttonCodeList = JSONUtil.toList(JSONUtil.parseArray(ext), ButtonPermission.class);
-            if (CollUtil.isNotEmpty(buttonCodeList)) {
-                Optional<ButtonPermission> firstPermission = buttonCodeList.stream().findFirst();
-                firstPermission.ifPresent(permission -> {
-                    Set<String> codeSet = Arrays.stream(permission.getValue().split(","))
-                        .map(String::trim)
-                        .filter(code -> !code.isEmpty())
-                        .collect(Collectors.toSet());
-                    buttonPermissions.forEach(bp -> bp.setShow(codeSet.contains(bp.getCode())));
-                });
-            }
-        }
-        return buttonPermissions;
-    }
+    private List<ButtonPermissionVo> buttonList;
+
 }

+ 22 - 0
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwNodeExtService.java

@@ -0,0 +1,22 @@
+package org.dromara.workflow.service;
+
+import org.dromara.workflow.domain.vo.ButtonPermissionVo;
+
+import java.util.List;
+
+/**
+ * 流程节点扩展属性 服务层
+ *
+ * @author AprilWind
+ */
+public interface IFlwNodeExtService {
+
+    /**
+     * 从扩展属性构建按钮权限列表:根据 ext 中记录的权限值,标记每个按钮是否勾选
+     *
+     * @param ext 扩展属性 JSON 字符串
+     * @return 按钮权限 VO 列表
+     */
+    List<ButtonPermissionVo> buildButtonPermissionsFromExt(String ext);
+
+}

+ 1 - 1
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java

@@ -191,7 +191,7 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
             List<FlowDefinition> flowDefinitions = flowDefinitionMapper.selectByIds(StreamUtils.toList(flowHisTasks, FlowHisTask::getDefinitionId));
             if (CollUtil.isNotEmpty(flowDefinitions)) {
                 String join = StreamUtils.join(flowDefinitions, FlowDefinition::getFlowCode);
-                log.error("流程定义【{}】已被使用不可被删除!", join);
+                log.info("流程定义【{}】已被使用不可被删除!", join);
                 throw new ServiceException("流程定义【" + join + "】已被使用不可被删除!");
             }
         }

+ 80 - 2
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java

@@ -2,18 +2,25 @@ package org.dromara.workflow.service.impl;
 
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.domain.dto.DictTypeDTO;
 import org.dromara.common.core.service.DictService;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.warm.flow.ui.service.NodeExtService;
 import org.dromara.warm.flow.ui.vo.NodeExt;
 import org.dromara.workflow.common.ConditionalOnEnable;
 import org.dromara.workflow.common.enums.ButtonPermissionEnum;
 import org.dromara.workflow.common.enums.NodeExtEnum;
+import org.dromara.workflow.domain.vo.ButtonPermissionVo;
+import org.dromara.workflow.service.IFlwNodeExtService;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * 流程设计器-节点扩展属性
@@ -24,14 +31,15 @@ import java.util.*;
 @Slf4j
 @RequiredArgsConstructor
 @Service
-public class FlwNodeExtServiceImpl implements NodeExtService {
+public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService {
 
     /**
      * 存储不同 dictType 对应的配置信息
      */
     private static final Map<String, ButtonPermission> CHILD_NODE_MAP = new HashMap<>();
 
-    record ButtonPermission(String label, Integer type, Boolean must, Boolean multiple) {}
+    record ButtonPermission(String label, Integer type, Boolean must, Boolean multiple) {
+    }
 
     static {
         CHILD_NODE_MAP.put(ButtonPermissionEnum.class.getSimpleName(),
@@ -162,4 +170,74 @@ public class FlwNodeExtServiceImpl implements NodeExtService {
         return childNode;
     }
 
+    /**
+     * 从扩展属性构建按钮权限列表:根据 ext 中记录的权限值,标记每个按钮是否勾选
+     *
+     * @param ext 扩展属性 JSON 字符串
+     * @return 按钮权限 VO 列表
+     */
+    @Override
+    public List<ButtonPermissionVo> buildButtonPermissionsFromExt(String ext) {
+        // 解析 ext 为 Map<code, Set<value>>,用于标记权限
+        Map<String, Set<String>> permissionMap = JsonUtils.parseArray(ext, ButtonPermissionVo.class)
+            .stream()
+            .collect(Collectors.toMap(
+                ButtonPermissionVo::getCode,
+                item -> StringUtils.splitList(item.getValue()).stream()
+                    .map(String::trim)
+                    .filter(StrUtil::isNotBlank)
+                    .collect(Collectors.toSet()),
+                (a, b) -> b,
+                HashMap::new
+            ));
+
+        // 构建按钮权限列表,标记哪些按钮在 permissionMap 中出现(表示已勾选)
+        return buildPermissionsFromSources(permissionMap, List.of(ButtonPermissionEnum.class));
+    }
+
+    /**
+     * 将权限映射与按钮权限来源(枚举类或字典类型)进行匹配,生成权限视图列表
+     * <p>
+     * 使用说明:
+     * - sources 支持传入多个来源类型,支持 NodeExtEnum 枚举类 或 字典类型字符串(dictType)
+     * - 若需要扩展更多按钮权限,只需在 sources 中新增对应的枚举类或字典类型
+     * <p>
+     * 示例:
+     * buildPermissionsFromSources(permissionMap, List.of(ButtonPermissionEnum.class, "custom_button_dict"));
+     *
+     * @param permissionMap 权限映射
+     * @param sources       枚举类或字典类型列表
+     * @return 按钮权限视图对象列表
+     */
+    @SuppressWarnings("unchecked cast")
+    private List<ButtonPermissionVo> buildPermissionsFromSources(Map<String, Set<String>> permissionMap, List<Object> sources) {
+        return sources.stream()
+            .flatMap(source -> {
+                if (source instanceof Class<?> clazz && NodeExtEnum.class.isAssignableFrom(clazz)) {
+                    Set<String> selectedSet = permissionMap.getOrDefault(clazz.getSimpleName(), Collections.emptySet());
+                    return extractDictItems(this.buildChildNode((Class<? extends NodeExtEnum>) clazz), selectedSet).stream();
+                } else if (source instanceof String dictType) {
+                    Set<String> selectedSet = permissionMap.getOrDefault(dictType, Collections.emptySet());
+                    return extractDictItems(this.buildChildNode(dictType), selectedSet).stream();
+                }
+                return Stream.empty();
+            }).toList();
+    }
+
+    /**
+     * 从节点子项中提取字典项,并构建按钮权限视图对象列表
+     *
+     * @param childNode   子节点
+     * @param selectedSet 已选中的值集
+     * @return 按钮权限视图对象列表
+     */
+    private List<ButtonPermissionVo> extractDictItems(NodeExt.ChildNode childNode, Set<String> selectedSet) {
+        return Optional.ofNullable(childNode)
+            .map(NodeExt.ChildNode::getDict)
+            .orElse(List.of())
+            .stream()
+            .map(dict -> new ButtonPermissionVo(dict.getValue(), selectedSet.contains(dict.getValue())))
+            .toList();
+    }
+
 }

+ 5 - 3
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java

@@ -48,6 +48,7 @@ import org.dromara.workflow.handler.WorkflowPermissionHandler;
 import org.dromara.workflow.mapper.FlwCategoryMapper;
 import org.dromara.workflow.mapper.FlwTaskMapper;
 import org.dromara.workflow.service.IFlwCommonService;
+import org.dromara.workflow.service.IFlwNodeExtService;
 import org.dromara.workflow.service.IFlwTaskAssigneeService;
 import org.dromara.workflow.service.IFlwTaskService;
 import org.springframework.stereotype.Service;
@@ -86,6 +87,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
     private final FlowNodeMapper flowNodeMapper;
     private final IFlwTaskAssigneeService flwTaskAssigneeService;
     private final IFlwCommonService flwCommonService;
+    private final IFlwNodeExtService flwNodeExtService;
 
     /**
      * 启动任务
@@ -561,12 +563,12 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
         flowTaskVo.setFlowCode(definition.getFlowCode());
         flowTaskVo.setFlowName(definition.getFlowName());
         flowTaskVo.setBusinessId(instance.getBusinessId());
-        //设置按钮权限
-        FlowNode flowNode = getByNodeCode(flowTaskVo.getNodeCode(), instance.getDefinitionId());
+        FlowNode flowNode = this.getByNodeCode(flowTaskVo.getNodeCode(), instance.getDefinitionId());
         if (ObjectUtil.isNull(flowNode)) {
             throw new NullPointerException("当前【" + flowTaskVo.getNodeCode() + "】节点编码不存在");
         }
-        flowTaskVo.setButtonList(flowTaskVo.getButtonList(flowNode.getExt()));
+        //设置按钮权限
+        flowTaskVo.setButtonList(flwNodeExtService.buildButtonPermissionsFromExt(flowNode.getExt()));
         flowTaskVo.setNodeRatio(flowNode.getNodeRatio());
         flowTaskVo.setApplyNode(flowNode.getNodeCode().equals(flwCommonService.applyNodeCode(task.getDefinitionId())));
         return flowTaskVo;