diff --git a/pom.xml b/pom.xml
index cc86e9b83..3d8a5c7e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,7 +50,7 @@
8.7.2-20250101
- 1.6.6
+ 1.6.7-M1
3.2.2
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 2a134a977..86deca2b2 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -272,3 +272,11 @@ warm-flow:
ui: true
# 默认Authorization,如果有多个token,用逗号分隔
token-name: ${sa-token.token-name},clientid
+ # 流程状态对应的三元色
+ chart-status-color:
+ ## 未办理
+ - 157,255,0
+ ## 待办理
+ - 0,0,0
+ ## 已办理
+ - 255,200,0
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DeptDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DeptDTO.java
index 65c012faf..7b748b0b5 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DeptDTO.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DeptDTO.java
@@ -11,7 +11,6 @@ import java.io.Serializable;
*
* @author AprilWind
*/
-
@Data
@NoArgsConstructor
public class DeptDTO implements Serializable {
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DictDataDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DictDataDTO.java
new file mode 100644
index 000000000..dff1a75dd
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DictDataDTO.java
@@ -0,0 +1,41 @@
+package org.dromara.common.core.domain.dto;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 字典数据DTO
+ *
+ * @author AprilWind
+ */
+@Data
+@NoArgsConstructor
+public class DictDataDTO implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 字典标签
+ */
+ private String dictLabel;
+
+ /**
+ * 字典键值
+ */
+ private String dictValue;
+
+ /**
+ * 是否默认(Y是 N否)
+ */
+ private String isDefault;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DictTypeDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DictTypeDTO.java
new file mode 100644
index 000000000..43ab142c2
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DictTypeDTO.java
@@ -0,0 +1,41 @@
+package org.dromara.common.core.domain.dto;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 字典类型DTO
+ *
+ * @author AprilWind
+ */
+@Data
+@NoArgsConstructor
+public class DictTypeDTO implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 字典主键
+ */
+ private Long dictId;
+
+ /**
+ * 字典名称
+ */
+ private String dictName;
+
+ /**
+ * 字典类型
+ */
+ private String dictType;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java
index b78a7f257..7c5097764 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DictService.java
@@ -1,5 +1,9 @@
package org.dromara.common.core.service;
+import org.dromara.common.core.domain.dto.DictDataDTO;
+import org.dromara.common.core.domain.dto.DictTypeDTO;
+
+import java.util.List;
import java.util.Map;
/**
@@ -64,4 +68,20 @@ public interface DictService {
*/
Map getAllDictByDictType(String dictType);
+ /**
+ * 根据字典类型查询详细信息
+ *
+ * @param dictType 字典类型
+ * @return 字典类型详细信息
+ */
+ DictTypeDTO getDictTypeDto(String dictType);
+
+ /**
+ * 根据字典类型查询字典数据列表
+ *
+ * @param dictType 字典类型
+ * @return 字典数据列表
+ */
+ List getDictDataDto(String dictType);
+
}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java
index 1be0b7f40..acf2816e8 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java
@@ -1,5 +1,6 @@
package org.dromara.system.service.impl;
+import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -8,6 +9,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.domain.dto.DictDataDTO;
+import org.dromara.common.core.domain.dto.DictTypeDTO;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.DictService;
import org.dromara.common.core.utils.MapstructUtils;
@@ -249,10 +252,40 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
}
}
+ /**
+ * 获取字典下所有的字典值与标签
+ *
+ * @param dictType 字典类型
+ * @return dictValue为key,dictLabel为值组成的Map
+ */
@Override
public Map getAllDictByDictType(String dictType) {
- List list = selectDictDataByType(dictType);
+ List list = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
return StreamUtils.toMap(list, SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel);
}
+ /**
+ * 根据字典类型查询详细信息
+ *
+ * @param dictType 字典类型
+ * @return 字典类型详细信息
+ */
+ @Override
+ public DictTypeDTO getDictTypeDto(String dictType) {
+ SysDictTypeVo vo = SpringUtils.getAopProxy(this).selectDictTypeByType(dictType);
+ return BeanUtil.toBean(vo, DictTypeDTO.class);
+ }
+
+ /**
+ * 根据字典类型查询字典数据列表
+ *
+ * @param dictType 字典类型
+ * @return 字典数据列表
+ */
+ @Override
+ public List getDictDataDto(String dictType) {
+ List list = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
+ return BeanUtil.copyToList(list, DictDataDTO.class);
+ }
+
}
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
new file mode 100644
index 000000000..fe25268fc
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwNodeExtServiceImpl.java
@@ -0,0 +1,125 @@
+package org.dromara.workflow.service.impl;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+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.warm.flow.ui.service.NodeExtService;
+import org.dromara.warm.flow.ui.vo.NodeExt;
+import org.dromara.workflow.common.ConditionalOnEnable;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 流程设计器-节点扩展属性
+ *
+ * @author AprilWind
+ */
+@ConditionalOnEnable
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class FlwNodeExtServiceImpl implements NodeExtService {
+
+ /**
+ * 权限页
+ */
+ private static final String BUTTON_PERMISSION_TAB = "wf_button_tab";
+
+ /**
+ * 权限页页签名称
+ */
+ private static final String LIMITS_OF_AUTHORITY = "权限";
+
+ /**
+ * 字典类型逗号分隔
+ */
+ private static final String DICT_TYPES = "wf_button_permission";
+
+ /**
+ * 基础设置
+ */
+ private static final int TYPE_BASE_SETTING = 1;
+
+ /**
+ * 新页签
+ */
+ private static final int TYPE_NEW_TAB = 2;
+ private final DictService dictService;
+
+ /**
+ * 获取节点扩展属性
+ *
+ * @return 结果
+ */
+ @Override
+ public List getNodeExt() {
+ List nodeExtList = new ArrayList<>();
+ // 构建按钮权限页面
+ nodeExtList.add(buildNodeExt(BUTTON_PERMISSION_TAB, TYPE_NEW_TAB, DICT_TYPES));
+ return nodeExtList;
+ }
+
+ /**
+ * 构建一个 NodeExt 对象
+ *
+ * @param code 编码,此json中唯一
+ * @param type 节点类型,1:基础设置,2:新页签
+ * @return 返回构建好的 NodeExt 对象
+ */
+ private NodeExt buildNodeExt(String code, int type, String dictTypes) {
+ NodeExt nodeExt = new NodeExt();
+ // 从系统参数配置里面获取信息构建新页面或者基础设置
+ // 编码,此json中唯一
+ nodeExt.setCode(code);
+ // 1:基础设置 2:新页签
+ nodeExt.setType(type);
+ // 名称,如果type为新页签时,作为页签名称
+ nodeExt.setName(LIMITS_OF_AUTHORITY);
+ nodeExt.setChilds(StringUtils.splitList(dictTypes)
+ .stream().map(this::buildChildNode).toList()
+ );
+ return nodeExt;
+ }
+
+ /**
+ * 构建一个 ChildNode 对象
+ *
+ * @param dictType 字典类型
+ * @return 返回构建好的 ChildNode 对象
+ */
+ private NodeExt.ChildNode buildChildNode(String dictType) {
+ NodeExt.ChildNode childNode = new NodeExt.ChildNode();
+ if (StringUtils.isBlank(dictType)) {
+ return childNode;
+ }
+ DictTypeDTO dictTypeDTO = dictService.getDictTypeDto(dictType);
+ if (ObjectUtil.isNull(dictTypeDTO)) {
+ return childNode;
+ }
+ // 编码,此json中唯一
+ childNode.setCode(dictType);
+ // label名称
+ childNode.setLabel(dictTypeDTO.getDictName());
+ // 描述
+ childNode.setDesc(dictTypeDTO.getRemark());
+ // 1:输入框 2:输入框 3:下拉框 4:选择框
+ childNode.setType(4);
+ // 是否必填
+ childNode.setMust(false);
+ // 是否多选
+ childNode.setMultiple(true);
+ // 字典,下拉框和复选框时用到
+ childNode.setDict(dictService.getDictDataDto(dictType)
+ .stream().map(x ->
+ new NodeExt.DictItem(x.getDictLabel(), x.getDictValue(), Convert.toBool(x.getIsDefault(), false))
+ ).toList());
+ return childNode;
+ }
+
+}
diff --git a/script/sql/ry_workflow.sql b/script/sql/ry_workflow.sql
index 9455636a0..652f4c084 100644
--- a/script/sql/ry_workflow.sql
+++ b/script/sql/ry_workflow.sql
@@ -24,7 +24,7 @@ CREATE TABLE `flow_definition`
CREATE TABLE `flow_node`
(
- `id` bigint unsigned NOT NULL COMMENT '主键id',
+ `id` bigint NOT NULL COMMENT '主键id',
`node_type` tinyint(1) NOT NULL COMMENT '节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)',
`definition_id` bigint NOT NULL COMMENT '流程定义id',
`node_code` varchar(100) NOT NULL COMMENT '流程节点编码',
@@ -32,7 +32,6 @@ CREATE TABLE `flow_node`
`permission_flag` varchar(200) DEFAULT NULL COMMENT '权限标识(权限类型:权限标识,可以多个,用逗号隔开)',
`node_ratio` decimal(6, 3) DEFAULT NULL COMMENT '流程签署比例值',
`coordinate` varchar(100) DEFAULT NULL COMMENT '坐标',
- `skip_any_node` varchar(100) DEFAULT 'N' COMMENT '是否可以退回任意节点(Y是 N否)即将删除',
`any_node_skip` varchar(100) DEFAULT NULL COMMENT '任意结点跳转',
`listener_type` varchar(100) DEFAULT NULL COMMENT '监听器类型',
`listener_path` varchar(400) DEFAULT NULL COMMENT '监听器路径',
@@ -43,6 +42,7 @@ CREATE TABLE `flow_node`
`version` varchar(20) NOT NULL COMMENT '版本',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
+ `ext` text COMMENT '扩展属性',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志',
`tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id',
PRIMARY KEY (`id`) USING BTREE
diff --git a/script/sql/update/update_5.3.0-5.3.1.sql b/script/sql/update/update_5.3.0-5.3.1.sql
new file mode 100644
index 000000000..8c313b25b
--- /dev/null
+++ b/script/sql/update/update_5.3.0-5.3.1.sql
@@ -0,0 +1,6 @@
+ALTER TABLE `flow_node` DROP COLUMN `skip_any_node`;
+ALTER TABLE `flow_node`
+ ADD COLUMN `ext` text NULL COMMENT '扩展属性' AFTER `update_time`;
+
+INSERT INTO sys_dict_type VALUES (16, '000000', '按钮权限', 'wf_button_permission', 103, 1, sysdate(), NULL, NULL, '按钮权限列表');
+INSERT INTO sys_dict_data VALUES (60, '000000', 1, '是否弹窗选人', '1', 'wf_button_permission', '', 'default', 'N', 103, 1, sysdate(), NULL, NULL,'是否弹窗选人');