B4+B5 表达式调试三模式弹窗(共享组件)+ 编辑器出口内联试算
- 新增 views/flow/components/ExprEvalModal.vue(原型 S1-S5,宽 560→700):
1) 从办件导入:adminInstances(page1,size50) 的 filterable Select(#id·bizType/bizId·标题·提交人·时间+状态Tag)、
bizType distinct chips 筛选、选中即 formData 解析缩进填充(解析失败填原文+红字)、内置变量只读条
(instanceId/instanceVersion/bizType/bizId/submitterId;nodeId/nodeName 提示按调试目标自填;schId 不展示)
2) 从路由日志导入:detail(instanceId) 取 kind=ROUTE 行,表格 节点名/注册键/命中出口(空=未命中)/attempt/时间
+ 每行 rawResponse <pre>(>200 字截断、title 全量、无留痕显示「(无留痕)」);
「载入该办件变量并复现」= 填 formData + 保留表达式再求值;无 ROUTE 行给空态文案
3) 手动编写:原 textarea 语义保留 + 最近 50 条办件 formData 键聚合 chips(点击插光标处)+ 引导文案
可用变量 chips 点击插入表达式光标(selectionStart/End,无焦点退化追加);求值仍走 /admin/router/eval,
结果区四态文案(true/false/error/未求值)含线上行为说明与「宁挂起不误放行」口径
- Routers.vue:删旧内联求值弹窗(evalForm/evalResult/doEval),改挂 <ExprEvalModal v-model="exprVisible">
- ConditionBox.vue(B5/S6):EXPRESSION 模式出口表达式行右侧加「试算」小钮(@click.stop 不触发容器交互),
带该出口表达式打开同一弹窗
注意:本提交连带纳入了并发会话在 Routers.vue 的 6 行「来源」列改动(regAppKey 自注册标识,
属 SERVICE 收口工作),非本批次内容,review 时请单独留意
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
import { ref, onMounted } from "vue";
|
||||
import { Message, Tag } from "view-ui-plus";
|
||||
import MyConfirm from "@/components/MyConfirm";
|
||||
import ExprEvalModal from "@/views/flow/components/ExprEvalModal.vue";
|
||||
import { flowApi } from "@/api/module/flow";
|
||||
import { actionColumn } from "@/utils/tableActions";
|
||||
import { useElementHeight } from "@/utils/hook/useElementHeight";
|
||||
@@ -20,6 +21,12 @@ const columns = [
|
||||
{ title: "注册键", key: "routerKey", width: 220 },
|
||||
{ title: "名称", key: "name", width: 160 },
|
||||
{ title: "服务目录键", key: "serviceKey", width: 110 },
|
||||
{
|
||||
// 2026-10-12 SERVICE 收口:reg_app_key 非空=yh-flow-route starter 自注册行(归属应用)
|
||||
title: "来源",
|
||||
width: 160,
|
||||
render: (h: any, p: any) => h("span", p.row.regAppKey ? `自注册 · ${p.row.regAppKey}` : "手工"),
|
||||
},
|
||||
{ title: "判断端点", key: "path", minWidth: 300 },
|
||||
{
|
||||
title: "basePath",
|
||||
@@ -129,33 +136,11 @@ 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);
|
||||
// ---- 表达式调试(2026-10-10 四议题;2026-10-12 议题三改为三模式共享弹窗 ExprEvalModal)----
|
||||
const exprVisible = ref(false);
|
||||
|
||||
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;
|
||||
}
|
||||
exprVisible.value = true;
|
||||
}
|
||||
|
||||
onMounted(load);
|
||||
@@ -208,34 +193,7 @@ onMounted(load);
|
||||
</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>
|
||||
<ExprEvalModal v-model="exprVisible" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
// 分支按出口名互斥选路(运行时调判断服务/表达式求值),分支尾隐式汇合到容器后继。
|
||||
// 分支头部的出口名 Input 即 contentJson 里 CONDITION 命名出边的 name(判断接口 outlets 契约);
|
||||
// EXPRESSION 模式(2026-10-10)下分支头部再就地编辑出边 condition,序号即求值优先级。
|
||||
import { computed, inject } from "vue";
|
||||
import { computed, inject, ref } from "vue";
|
||||
import { BRANCH_LABELS, EDITOR_CTX, MAX_BRANCHES, MIN_BRANCHES, ConditionNode } from "../model";
|
||||
import NodeList from "./NodeList.vue";
|
||||
import ExprEvalModal from "@/views/flow/components/ExprEvalModal.vue";
|
||||
|
||||
const props = defineProps<{ node: ConditionNode }>();
|
||||
|
||||
@@ -35,6 +36,15 @@ function editCondition(i: number, v: string): void {
|
||||
while (props.node.conditions.length <= i) props.node.conditions.push("");
|
||||
props.node.conditions[i] = v;
|
||||
}
|
||||
|
||||
// B5 内联试算:把该出口表达式带进共享调试弹窗(ExprEvalModal)
|
||||
const tryVisible = ref(false);
|
||||
const tryExpr = ref("");
|
||||
|
||||
function openTry(i: number): void {
|
||||
tryExpr.value = (props.node.conditions || [])[i] || "";
|
||||
tryVisible.value = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -69,14 +79,17 @@ function editCondition(i: number, v: string): void {
|
||||
<span class="cb-col-del" title="删除分支">×</span>
|
||||
</Poptip>
|
||||
</div>
|
||||
<input
|
||||
v-if="expression"
|
||||
class="cb-cond"
|
||||
:value="(node.conditions || [])[i] || ''"
|
||||
placeholder="条件表达式,如 amount > 1000"
|
||||
maxlength="200"
|
||||
@input="editCondition(i, ($event.target as HTMLInputElement).value)"
|
||||
/>
|
||||
<div v-if="expression" class="cb-cond-row">
|
||||
<input
|
||||
class="cb-cond"
|
||||
:value="(node.conditions || [])[i] || ''"
|
||||
placeholder="条件表达式,如 amount > 1000"
|
||||
maxlength="200"
|
||||
@input="editCondition(i, ($event.target as HTMLInputElement).value)"
|
||||
/>
|
||||
<!-- B5 内联试算:用真实办件变量跑该出口表达式(同「条件路由」页弹窗,预填表达式) -->
|
||||
<span class="cb-try" title="用真实办件变量试算该表达式" @click.stop="openTry(i)">试算</span>
|
||||
</div>
|
||||
<NodeList :items="branch" :container="`${node.uid}:${i}`" />
|
||||
<div v-if="!branch.length" class="cb-empty">该出口直达汇合点(直接通过)</div>
|
||||
</div>
|
||||
@@ -85,6 +98,7 @@ function editCondition(i: number, v: string): void {
|
||||
+ 添加分支
|
||||
</Button>
|
||||
<div v-for="(issue, k) in issues" :key="k" class="cb-issue" :class="issue.level">⚠ {{ issue.text }}</div>
|
||||
<ExprEvalModal v-model="tryVisible" :preset-expression="tryExpr" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -192,6 +206,31 @@ function editCondition(i: number, v: string): void {
|
||||
.cb-cond::placeholder {
|
||||
color: #c5b3e8;
|
||||
}
|
||||
.cb-cond-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.cb-cond-row .cb-cond {
|
||||
flex: 1;
|
||||
width: auto;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.cb-try {
|
||||
flex: none;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
color: #0b7d72;
|
||||
border: 1px solid #b7e3dc;
|
||||
border-radius: 10px;
|
||||
padding: 0 8px;
|
||||
line-height: 18px;
|
||||
user-select: none;
|
||||
}
|
||||
.cb-try:hover {
|
||||
background: #f2fbf9;
|
||||
border-color: #0b7d72;
|
||||
}
|
||||
.cb-col-del {
|
||||
flex: none;
|
||||
cursor: pointer;
|
||||
|
||||
Reference in New Issue
Block a user