feat(condition): 编辑器支持表达式判断——判断方式切换 + 出口条件就地编辑 + 表达式调试

- ConditionNode 增 judgeMode/conditions(SERVICE 缺省,旧定义天然兼容);DefEdgeJson/DefNodeJson 透传 condition/judgeMode
- convert.ts 双向透传:CONDITION 分支首边带 condition,序列化顺序=分支顺序(求值优先级保序)
- ConditionDrawer 判断方式 Radio(服务/表达式);ConditionBox 表达式模式分支头部条件输入(序号即优先级)
- validate.ts 镜像校验:表达式模式每出口条件必填(语法由后端发布期拦)
- Routers 页加「表达式调试」Modal(/admin/router/eval,与线上同一求值核心)
- addBranch/removeBranch 同步维护 conditions 占位
This commit is contained in:
chenxing
2026-10-10 18:52:54 +08:00
parent a4cc8ea2fa
commit acbf601e7a
8 changed files with 205 additions and 20 deletions
+59
View File
@@ -131,6 +131,35 @@ function onEnable(row: any) {
});
}
// ---- 表达式调试(2026-10-10 四议题):与运行时同一求值核心(/admin/router/eval) ----
const evalVisible = ref(false);
const evaluating = ref(false);
const evalForm = ref<{ expression: string; variablesJson: string }>({ expression: "", variablesJson: "" });
const evalResult = ref<{ result: boolean; value?: string; error?: string } | null>(null);
function onEval() {
evalForm.value = { expression: "", variablesJson: "" };
evalResult.value = null;
evalVisible.value = true;
}
async function doEval() {
if (!evalForm.value.expression.trim()) {
Message.warning("请填写表达式");
return;
}
evaluating.value = true;
evalResult.value = null;
try {
evalResult.value = (await flowApi.routerEval({
expression: evalForm.value.expression.trim(),
variablesJson: evalForm.value.variablesJson.trim(),
}).send()) || null;
} finally {
evaluating.value = false;
}
}
onMounted(load);
</script>
@@ -139,6 +168,7 @@ onMounted(load);
<div class="main-container">
<div class="fix mb-12">
<Button class="fl" type="primary" size="large" @click="onAdd">新增注册</Button>
<Button class="fl" size="large" style="margin-left: 8px" @click="onEval">表达式调试</Button>
</div>
<div class="search-wrap fix">
@@ -177,6 +207,35 @@ onMounted(load);
<Button type="primary" :loading="saving" @click="onSave">提交</Button>
</template>
</Modal>
<Modal v-model="evalVisible" title="表达式调试" :mask-closable="false" :width="560">
<p style="color: #808695; font-size: 12px; line-height: 1.6; margin-bottom: 10px">
与 CONDITION 节点 EXPRESSION 模式同一套求值(AviatorScript 沙箱)。变量 = 样例 JSON 的
键 + 线上另注入 schId/bizType/bizId/submitterId/instanceId/instanceVersion/nodeId/nodeName
(调试时请在样例里自行提供内置变量取值)。变量未提供会报错——线上同口径(宁挂起不误放行)
</p>
<Input v-model="evalForm.expression" placeholder="表达式,如 amount > 1000" :maxlength="200"
style="margin-bottom: 8px" />
<Input v-model="evalForm.variablesJson" type="textarea" :rows="5"
placeholder='样例变量 JSON,如 {"amount": 2000, "bizType": "leave"}' />
<div v-if="evalResult" style="margin-top: 10px; font-size: 13px">
<template v-if="evalResult.error">
<span style="color: #ed4014">✗ 求值失败:{{ evalResult.error }}</span>
</template>
<template v-else>
<span :style="{ color: evalResult.result ? '#19be6b' : '#ff9900' }">
{{ evalResult.result ? "✓ true(命中该出口)" : "✗ false(不命中)" }}
</span>
<span v-if="evalResult.value !== undefined" style="color: #808695; margin-left: 8px">
求值值:{{ evalResult.value }}
</span>
</template>
</div>
<template #footer>
<Button @click="evalVisible = false">关闭</Button>
<Button type="primary" :loading="evaluating" @click="doEval">求值</Button>
</template>
</Modal>
</div>
</div>
</template>