diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ButtonPermission.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ButtonPermissionVo.java similarity index 61% rename from ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ButtonPermission.java rename to ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ButtonPermissionVo.java index 51f320d2d..eb26a4502 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ButtonPermission.java +++ b/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; + } + } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowTaskVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowTaskVo.java index 785e866c8..e3b37ed86 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowTaskVo.java +++ b/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 buttonList; + private List buttonList; - public List getButtonList(String ext) { - List 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 buttonCodeList = JSONUtil.toList(JSONUtil.parseArray(ext), ButtonPermission.class); - if (CollUtil.isNotEmpty(buttonCodeList)) { - Optional firstPermission = buttonCodeList.stream().findFirst(); - firstPermission.ifPresent(permission -> { - Set 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; - } } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwNodeExtService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwNodeExtService.java new file mode 100644 index 000000000..959516535 --- /dev/null +++ b/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 buildButtonPermissionsFromExt(String ext); + +} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java index 7f0f67ec6..7936210d0 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java @@ -191,7 +191,7 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService { List 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 + "】已被使用不可被删除!"); } } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java index a6af73988..fca21a367 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java +++ b/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 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 buildButtonPermissionsFromExt(String ext) { + // 解析 ext 为 Map>,用于标记权限 + Map> 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)); + } + + /** + * 将权限映射与按钮权限来源(枚举类或字典类型)进行匹配,生成权限视图列表 + *

+ * 使用说明: + * - sources 支持传入多个来源类型,支持 NodeExtEnum 枚举类 或 字典类型字符串(dictType) + * - 若需要扩展更多按钮权限,只需在 sources 中新增对应的枚举类或字典类型 + *

+ * 示例: + * buildPermissionsFromSources(permissionMap, List.of(ButtonPermissionEnum.class, "custom_button_dict")); + * + * @param permissionMap 权限映射 + * @param sources 枚举类或字典类型列表 + * @return 按钮权限视图对象列表 + */ + @SuppressWarnings("unchecked cast") + private List buildPermissionsFromSources(Map> permissionMap, List sources) { + return sources.stream() + .flatMap(source -> { + if (source instanceof Class clazz && NodeExtEnum.class.isAssignableFrom(clazz)) { + Set selectedSet = permissionMap.getOrDefault(clazz.getSimpleName(), Collections.emptySet()); + return extractDictItems(this.buildChildNode((Class) clazz), selectedSet).stream(); + } else if (source instanceof String dictType) { + Set selectedSet = permissionMap.getOrDefault(dictType, Collections.emptySet()); + return extractDictItems(this.buildChildNode(dictType), selectedSet).stream(); + } + return Stream.empty(); + }).toList(); + } + + /** + * 从节点子项中提取字典项,并构建按钮权限视图对象列表 + * + * @param childNode 子节点 + * @param selectedSet 已选中的值集 + * @return 按钮权限视图对象列表 + */ + private List extractDictItems(NodeExt.ChildNode childNode, Set selectedSet) { + return Optional.ofNullable(childNode) + .map(NodeExt.ChildNode::getDict) + .orElse(List.of()) + .stream() + .map(dict -> new ButtonPermissionVo(dict.getValue(), selectedSet.contains(dict.getValue()))) + .toList(); + } + } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index 71f2a53f2..90c96a4f4 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/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;