feat(sj_map_reduce): 工作流条件分支新增模拟上下文字段
This commit is contained in:
parent
bbf57da298
commit
974b286bd0
116
src/components/common/dynamic-input.vue
Normal file
116
src/components/common/dynamic-input.vue
Normal 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>
|
@ -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>
|
||||||
|
@ -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,
|
||||||
|
@ -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))
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
src/typings/workflow.d.ts
vendored
2
src/typings/workflow.d.ts
vendored
@ -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;
|
||||||
/** 判定逻辑 */
|
/** 判定逻辑 */
|
||||||
|
@ -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;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user