feat(sj_map_reduce): 工作流条件分支新增模拟上下文字段

This commit is contained in:
xlsea 2024-07-01 15:39:32 +08:00
parent bbf57da298
commit 974b286bd0
6 changed files with 150 additions and 3 deletions

View File

@ -0,0 +1,116 @@
<script setup lang="ts">
const content = defineModel<{ key: string; value: string | number | boolean; type: string }[]>('value', {
required: true,
default: () => []
});
const path = defineModel<string>('path', {
required: true
});
const onCreate = () => {
return {
key: '',
value: '',
type: 'string'
};
};
const dynamicInputRule = [
{
trigger: ['input', 'blur'],
validator(_: unknown, value: string) {
if (!value) return new Error('不能为空');
return true;
}
}
];
const typeOptions = [
{
label: 'string',
value: 'string'
},
{
label: 'number',
value: 'number'
},
{
label: 'boolean',
value: 'boolean'
}
];
const boolenOptions = [
{
label: 'true',
value: 0
},
{
label: 'false',
value: 1
}
];
</script>
<template>
<NDynamicInput v-model:value="content" item-style="margin-bottom: 0;" :on-create="onCreate" #="{ index }">
<div class="flex">
<NFormItem
ignore-path-change
:show-label="false"
:show-feedback="false"
:rule="dynamicInputRule"
:path="`${path}[${index}].key`"
>
<NInput v-model:value="content[index].key" placeholder="key" @keydown.enter.prevent />
</NFormItem>
<div class="mx-8px h-34px lh-34px">=</div>
<NFormItem
ignore-path-change
:show-label="false"
:show-feedback="false"
:rule="dynamicInputRule"
:path="`${path}[${index}].value`"
>
<NInput
v-if="content[index].type === 'string'"
v-model:value="content[index].value as string"
placeholder="value"
@keydown.enter.prevent
/>
<NInputNumber
v-if="content[index].type === 'number'"
v-model:value="content[index].value as number"
placeholder="value"
@keydown.enter.prevent
/>
<NSelect
v-if="content[index].type === 'boolen'"
v-model:value="content[index].value as number"
:options="boolenOptions"
placeholder="value"
@keydown.enter.prevent
/>
</NFormItem>
<div class="mx-3px h-34px lh-34px">(</div>
<NFormItem
class="w-170px"
ignore-path-change
:show-label="false"
:show-feedback="false"
:path="`${path}[${index}].type`"
>
<NSelect
v-model:value="content[index].type"
:options="typeOptions"
placeholder="字段类型"
@keydown.enter.prevent
/>
</NFormItem>
<div class="ml-3px h-34px lh-34px">)</div>
</div>
</NDynamicInput>
</template>
<style scoped></style>

View File

@ -35,7 +35,8 @@ const drawer = ref<boolean>(false);
const form = ref<Workflow.ConditionNodeType>({ const form = ref<Workflow.ConditionNodeType>({
decision: { decision: {
logicalCondition: 1, logicalCondition: 1,
expressionType: 1 expressionType: 1,
checkContent: []
} }
}); });
@ -93,6 +94,8 @@ const checkNodeExpression = async () => {
if (data.key !== 1) { if (data.key !== 1) {
return Promise.reject(data.value ?? '请检查条件表达式'); return Promise.reject(data.value ?? '请检查条件表达式');
} }
} else {
return Promise.reject(new Error('接口请求失败'));
} }
return Promise.resolve(); return Promise.resolve();
}; };
@ -153,6 +156,9 @@ const rules: FormRules = {
:extensions="[oneDark]" :extensions="[oneDark]"
/> />
</NFormItem> </NFormItem>
<NFormItem path="decision.checkContent" label="模拟上下文">
<DynamicInput v-model:value="form.decision!.checkContent!" path="decision.checkContent" />
</NFormItem>
</NForm> </NForm>
<template #footer> <template #footer>

View File

@ -44,7 +44,7 @@ watch(
const addTerm = () => { const addTerm = () => {
const len = nodeConfig.value.conditionNodes!.length; const len = nodeConfig.value.conditionNodes!.length;
nodeConfig.value.conditionNodes!.splice(-1, 0, { nodeConfig.value.conditionNodes!.splice(-1, 0, {
nodeName: `${$t('workflow.node.condition.nodeName')} ${len}`, nodeName: `${$t('workflow.node.condition.conditionNodes.nodeName')} ${len}`,
priorityLevel: len, priorityLevel: len,
decision: { decision: {
expressionType: 1, expressionType: 1,

View File

@ -1,3 +1,4 @@
import { parseContent } from '@/utils/common';
import { request } from '../request'; import { request } from '../request';
/** get workflow page list */ /** get workflow page list */
@ -67,7 +68,10 @@ export function fetchCheckNodeExpression(expression: Workflow.BrachNodeType) {
return request<{ key: number; value: string }>({ return request<{ key: number; value: string }>({
url: '/workflow/check-node-expression', url: '/workflow/check-node-expression',
method: 'post', method: 'post',
data: expression data: {
...expression,
checkContent: JSON.stringify(parseContent(expression.checkContent))
}
}); });
} }

View File

@ -85,6 +85,8 @@ declare namespace Workflow {
type BrachNodeType = { type BrachNodeType = {
/** 条件节点表达式 */ /** 条件节点表达式 */
nodeExpression?: string; nodeExpression?: string;
/** 模拟上下文 */
checkContent?: { key: string; value: string | number | boolean; type: string }[];
/** 表达式类型 */ /** 表达式类型 */
expressionType?: Api.Common.Expression; expressionType?: Api.Common.Expression;
/** 判定逻辑 */ /** 判定逻辑 */

View File

@ -160,3 +160,22 @@ export function parseArgsJson(value: string) {
return argsJson; return argsJson;
} }
export function parseContent(value?: { key: string; value: string | number | boolean; type: string }[]) {
if (!value) return undefined;
return value.reduce<{ [key: string]: string | number | boolean }>((obj, item) => {
if (item.type === 'string') {
obj[item.key] = String(item.value);
}
if (item.type === 'boolean') {
obj[item.key] = item.value === 0;
}
if (item.type === 'number') {
obj[item.key] = Number(item.value);
}
return obj;
}, {});
}