mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2025-11-12 20:23:50 +08:00
update warm-flow 升级 1.8.2
This commit is contained in:
@@ -72,8 +72,8 @@ public class WorkflowGlobalListener implements GlobalListener {
|
||||
public void start(ListenerVariable listenerVariable) {
|
||||
String ext = listenerVariable.getNode().getExt();
|
||||
if (StringUtils.isNotBlank(ext)) {
|
||||
NodeExtVo nodeExt = nodeExtService.parseNodeExt(ext);
|
||||
Map<String, Object> variable = listenerVariable.getVariable();
|
||||
NodeExtVo nodeExt = nodeExtService.parseNodeExt(ext, variable);
|
||||
Set<String> copyList = nodeExt.getCopySettings();
|
||||
if (CollUtil.isNotEmpty(copyList)) {
|
||||
List<FlowCopyBo> list = StreamUtils.toList(copyList, x -> {
|
||||
@@ -180,12 +180,14 @@ public class WorkflowGlobalListener implements GlobalListener {
|
||||
}
|
||||
|
||||
if (variable.containsKey(FlowConstant.FLOW_COPY_LIST)) {
|
||||
List<FlowCopyBo> flowCopyList = MapUtil.get(variable, FlowConstant.FLOW_COPY_LIST, new TypeReference<>() {});
|
||||
List<FlowCopyBo> flowCopyList = MapUtil.get(variable, FlowConstant.FLOW_COPY_LIST, new TypeReference<>() {
|
||||
});
|
||||
// 添加抄送人
|
||||
flwTaskService.setCopy(task, flowCopyList);
|
||||
}
|
||||
if (variable.containsKey(FlowConstant.MESSAGE_TYPE)) {
|
||||
List<String> messageType = MapUtil.get(variable, FlowConstant.MESSAGE_TYPE, new TypeReference<>() {});
|
||||
List<String> messageType = MapUtil.get(variable, FlowConstant.MESSAGE_TYPE, new TypeReference<>() {
|
||||
});
|
||||
String notice = MapUtil.getStr(variable, FlowConstant.MESSAGE_NOTICE);
|
||||
flwCommonService.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.dromara.workflow.service;
|
||||
|
||||
import org.dromara.workflow.domain.vo.NodeExtVo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 流程节点扩展属性 服务层
|
||||
*
|
||||
@@ -24,9 +26,10 @@ public interface IFlwNodeExtService {
|
||||
* {"code": "VariablesEnum", "value": "key1=value1,key2=value2"}
|
||||
* ]
|
||||
*
|
||||
* @param ext 扩展属性 JSON 字符串
|
||||
* @param ext 扩展属性 JSON 字符串
|
||||
* @param variable 流程变量
|
||||
* @return NodeExtVo 对象,封装按钮权限列表、抄送对象集合和自定义参数 Map
|
||||
*/
|
||||
NodeExtVo parseNodeExt(String ext);
|
||||
NodeExtVo parseNodeExt(String ext, Map<String, Object> variable);
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@ 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.core.FlowEngine;
|
||||
import org.dromara.warm.flow.core.utils.CollUtil;
|
||||
import org.dromara.warm.flow.core.utils.ExpressionUtil;
|
||||
import org.dromara.warm.flow.ui.service.NodeExtService;
|
||||
import org.dromara.warm.flow.ui.vo.NodeExt;
|
||||
import org.dromara.workflow.common.ConditionalOnEnable;
|
||||
@@ -45,7 +48,7 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService
|
||||
CopySettingEnum.class.getSimpleName(),
|
||||
Map.of(
|
||||
"label", "抄送对象",
|
||||
"type", 2,
|
||||
"type", 5,
|
||||
"must", false,
|
||||
"multiple", false,
|
||||
"desc", "设置该节点的抄送办理人"
|
||||
@@ -56,7 +59,7 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService
|
||||
"type", 2,
|
||||
"must", false,
|
||||
"multiple", false,
|
||||
"desc", "节点执行时可以使用的自定义参数"
|
||||
"desc", "节点执行时可设置自定义参数,多个参数以逗号分隔,如:key1=value1,key2=value2"
|
||||
),
|
||||
ButtonPermissionEnum.class.getSimpleName(),
|
||||
Map.of(
|
||||
@@ -137,7 +140,7 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService
|
||||
childNode.setCode(simpleName);
|
||||
// label名称
|
||||
childNode.setLabel(Convert.toStr(map.get("label")));
|
||||
// 1:输入框 2:文本域 3:下拉框 4:选择框
|
||||
// 1:输入框 2:文本域 3:下拉框 4:选择框 5:用户选择器
|
||||
childNode.setType(Convert.toInt(map.get("type"), 1));
|
||||
// 是否必填
|
||||
childNode.setMust(Convert.toBool(map.get("must"), false));
|
||||
@@ -170,7 +173,7 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService
|
||||
childNode.setCode(dictType);
|
||||
// label名称
|
||||
childNode.setLabel(dictTypeDTO.getDictName());
|
||||
// 1:输入框 2:文本域 3:下拉框 4:选择框
|
||||
// 1:输入框 2:文本域 3:下拉框 4:选择框 5:用户选择器
|
||||
childNode.setType(3);
|
||||
// 是否必填
|
||||
childNode.setMust(false);
|
||||
@@ -197,15 +200,16 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService
|
||||
* <p>示例 JSON:
|
||||
* [
|
||||
* {"code": "ButtonPermissionEnum", "value": "back,termination"},
|
||||
* {"code": "CopySettingEnum", "value": "1"},
|
||||
* {"code": "CopySettingEnum", "value": "1,3,4,#{@spelRuleComponent.selectDeptLeaderById(#deptId", "#roleId)}"},
|
||||
* {"code": "VariablesEnum", "value": "key1=value1,key2=value2"}
|
||||
* ]
|
||||
*
|
||||
* @param ext 扩展属性 JSON 字符串
|
||||
* @param ext 扩展属性 JSON 字符串
|
||||
* @param variable 流程变量
|
||||
* @return NodeExtVo 对象,封装按钮权限列表、抄送对象集合和自定义参数 Map
|
||||
*/
|
||||
@Override
|
||||
public NodeExtVo parseNodeExt(String ext) {
|
||||
public NodeExtVo parseNodeExt(String ext, Map<String, Object> variable) {
|
||||
NodeExtVo nodeExtVo = new NodeExtVo();
|
||||
|
||||
// 解析 JSON 为 Dict 列表
|
||||
@@ -234,8 +238,20 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService
|
||||
nodeExtVo.setButtonPermissions(buttonList);
|
||||
|
||||
} else if (CopySettingEnum.class.getSimpleName().equals(code)) {
|
||||
List<String> permissions = spelSmartSplit(value).stream()
|
||||
.map(s -> {
|
||||
List<String> result = ExpressionUtil.evalVariable(s, variable);
|
||||
if (CollUtil.isNotEmpty(result)) {
|
||||
return result;
|
||||
}
|
||||
return Collections.singletonList(s);
|
||||
}).filter(Objects::nonNull)
|
||||
.flatMap(List::stream)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
List<String> copySettings = FlowEngine.permissionHandler().convertPermissions(permissions);
|
||||
// 解析抄送对象 ID 集合
|
||||
nodeExtVo.setCopySettings(StringUtils.str2Set(value, StringUtils.SEPARATOR));
|
||||
nodeExtVo.setCopySettings(new HashSet<>(copySettings));
|
||||
|
||||
} else if (VariablesEnum.class.getSimpleName().equals(code)) {
|
||||
// 解析自定义参数
|
||||
@@ -254,4 +270,82 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService
|
||||
return nodeExtVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按逗号分割字符串,但保留 #{...} 表达式和字符串常量中的逗号
|
||||
*/
|
||||
private static List<String> spelSmartSplit(String str) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if (str == null || str.trim().isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
StringBuilder token = new StringBuilder();
|
||||
// #{...} 的嵌套深度
|
||||
int depth = 0;
|
||||
// 是否在字符串常量中(" 或 ')
|
||||
boolean inString = false;
|
||||
// 当前字符串引号类型
|
||||
char stringQuote = 0;
|
||||
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char c = str.charAt(i);
|
||||
|
||||
// 检测进入 SpEL 表达式 #{...}
|
||||
if (!inString && c == '#' && depth == 0 && checkNext(str, i, '{')) {
|
||||
depth++;
|
||||
token.append("#{");
|
||||
// 跳过 {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 在表达式中遇到 { 或 } 改变嵌套深度
|
||||
if (!inString && depth > 0) {
|
||||
if (c == '{') {
|
||||
depth++;
|
||||
} else if (c == '}') {
|
||||
depth--;
|
||||
}
|
||||
token.append(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检测字符串开始/结束
|
||||
if (depth > 0 && (c == '"' || c == '\'')) {
|
||||
if (!inString) {
|
||||
inString = true;
|
||||
stringQuote = c;
|
||||
} else if (stringQuote == c) {
|
||||
inString = false;
|
||||
}
|
||||
token.append(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 外层逗号才分割
|
||||
if (c == ',' && depth == 0 && !inString) {
|
||||
String part = token.toString().trim();
|
||||
if (!part.isEmpty()) {
|
||||
result.add(part);
|
||||
}
|
||||
token.setLength(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
token.append(c);
|
||||
}
|
||||
|
||||
// 添加最后一个
|
||||
String part = token.toString().trim();
|
||||
if (!part.isEmpty()) {
|
||||
result.add(part);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean checkNext(String str, int index, char expected) {
|
||||
return index + 1 < str.length() && str.charAt(index + 1) == expected;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -598,7 +598,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
if (ObjectUtil.isNull(flowNode)) {
|
||||
throw new NullPointerException("当前【" + flowTaskVo.getNodeCode() + "】节点编码不存在");
|
||||
}
|
||||
NodeExtVo nodeExtVo = flwNodeExtService.parseNodeExt(flowNode.getExt());
|
||||
NodeExtVo nodeExtVo = flwNodeExtService.parseNodeExt(flowNode.getExt(), instance.getVariableMap());
|
||||
//设置按钮权限
|
||||
flowTaskVo.setButtonList(nodeExtVo.getButtonPermissions());
|
||||
if (CollUtil.isNotEmpty(nodeExtVo.getCopySettings())) {
|
||||
|
||||
Reference in New Issue
Block a user