diff --git a/ui/src/components/ai-chat/component/inline-params/constants.ts b/ui/src/components/ai-chat/component/inline-params/constants.ts index d4fe24ce528..e98cf6dbe2a 100644 --- a/ui/src/components/ai-chat/component/inline-params/constants.ts +++ b/ui/src/components/ai-chat/component/inline-params/constants.ts @@ -15,6 +15,4 @@ export const ALLOWED_EXPOSED_TYPES = [ 'TreeSelect', 'SingleSelect', 'MultiSelect', - 'RadioCard', - 'RadioRow', ] as const diff --git a/ui/src/components/ai-chat/component/inline-params/index.vue b/ui/src/components/ai-chat/component/inline-params/index.vue index 2ccb7e658c8..f4ec018522b 100644 --- a/ui/src/components/ai-chat/component/inline-params/index.vue +++ b/ui/src/components/ai-chat/component/inline-params/index.vue @@ -24,7 +24,7 @@ import { ref, watch, computed, onMounted } from 'vue' import type { FormField } from '@/components/dynamics-form/type' import type { Dict } from '@/api/type/common' -import { evaluateVisibility } from '@/components/dynamics-form/visibility' +import { computeVisibilityMap } from '@/components/dynamics-form/visibility' import InlineFormItem from './InlineFormItem.vue' import { t } from '@/locales' import _ from 'lodash' @@ -169,6 +169,8 @@ const dialogFields = computed(() => { return fieldList.value.filter((f) => !setting.value.exposed_fields.includes(f.field)) }) +const visibilityMap = computed(() => computeVisibilityMap(fieldList.value, formValue.value)) + const show = (field: FormField) => { if (field.relation_show_field_dict) { const keys = Object.keys(field.relation_show_field_dict) @@ -188,17 +190,19 @@ const show = (field: FormField) => { } } if (field.visibility_rules?.node_id) { - return evaluateVisibility(field.visibility_rules, { - formValue: formValue.value, - currentNodeId: field.visibility_rules.node_id, - currentNodeName: field.visibility_rules.node_name || '', - }) + return visibilityMap.value[field.field] ?? true } return true } defineExpose({ validate: () => { + for (const field of fieldList.value) { + if (!show(field)) { + formValue.value[field.field] = null + } + } + for (const item of exposedFields.value) { if (!show(item)) continue const isRequired = item.required ?? item.is_required diff --git a/ui/src/components/dynamics-form/index.vue b/ui/src/components/dynamics-form/index.vue index 64bcaf47199..caa79740a2d 100644 --- a/ui/src/components/dynamics-form/index.vue +++ b/ui/src/components/dynamics-form/index.vue @@ -36,12 +36,12 @@ import type { Dict } from '@/api/type/common' import FormItem from '@/components/dynamics-form/FormItem.vue' import type { FormField } from '@/components/dynamics-form/type' -import { ref, onBeforeMount, watch, type Ref, nextTick } from 'vue' +import { ref, onBeforeMount, watch, type Ref, nextTick, computed } from 'vue' import type { FormInstance } from 'element-plus' import type Result from '@/request/Result' import _ from 'lodash' import { get, post, put, del } from '@/request/index' -import { evaluateVisibility } from './visibility' +import { computeVisibilityMap } from './visibility' const request = { get, post, @@ -81,6 +81,9 @@ const formFieldList = ref>([]) const ruleFormRef = ref() const formFieldRef = ref>>([]) + +const visibilityMap = computed(() => computeVisibilityMap(formFieldList.value, formValue.value)) + /** * 当前 field是否展示 * @param field @@ -106,11 +109,7 @@ const show = (field: FormField) => { // new if (field.visibility_rules?.node_id) { - return evaluateVisibility(field.visibility_rules, { - formValue: formValue.value, - currentNodeId: field.visibility_rules.node_id, - currentNodeName: field.visibility_rules.node_name || '', - }) + return visibilityMap.value[field.field] ?? true } return true diff --git a/ui/src/components/dynamics-form/visibility/index.ts b/ui/src/components/dynamics-form/visibility/index.ts index 069fe344bb5..92bf02fb7f1 100644 --- a/ui/src/components/dynamics-form/visibility/index.ts +++ b/ui/src/components/dynamics-form/visibility/index.ts @@ -154,3 +154,35 @@ export function evaluateVisibility( return rules.action === 'show' ? matched : !matched } + +/** + * 单向扫描计算整个字段列表的显隐表。 + * @param fields + * @param formValue + * @returns { 字段名: 是否可见 } 的 map + */ +export function computeVisibilityMap( + fields: Array<{ field: string; visibility_rules?: VisibilityRules }>, + formValue: Record, +): Record { + const copy: Record = { ...formValue } + const map: Record = {} + + for (const f of fields) { + if (!f.visibility_rules?.node_id) { + map[f.field] = true + continue + } + + const visible = evaluateVisibility(f.visibility_rules, { + formValue: copy, + currentNodeId: f.visibility_rules.node_id, + currentNodeName: f.visibility_rules.node_name || '', + }) + map[f.field] = visible + if (!visible) { + copy[f.field] = null + } + } + return map +} diff --git a/ui/src/workflow/nodes/form-node/index.vue b/ui/src/workflow/nodes/form-node/index.vue index 78764043622..b6a34422a27 100644 --- a/ui/src/workflow/nodes/form-node/index.vue +++ b/ui/src/workflow/nodes/form-node/index.vue @@ -281,6 +281,11 @@ const validate = () => { const v_list = [formNodeFormRef.value?.validate()] const upstreamNodes = props.nodeModel.get_up_node_field_list(true, true) + if (props.nodeModel.graphModel.get_up_node_field_list) { + const outer = props.nodeModel.graphModel.get_up_node_field_list(true, true) + outer.forEach((item: any) => upstreamNodes.push(item)) + } + for (const field of form_data.value.form_field_list) { for (const cond of field.visibility_rules?.conditions || []) { if (!cond.field || cond.field.length < 2 || !cond.field[0] || !cond.field[1]) continue @@ -290,16 +295,8 @@ const validate = () => { v_list.push(Promise.reject(t('workflow.variable.NoReferencing'))) } } else { - // 跨节点:查上游 + // 跨节点:查上游(含循环外层 graph 的节点) const nodeEntry = upstreamNodes.find((n: any) => n.value === cond.field[0]) - console.log('cond.field:', cond.field) - console.log( - 'upstreamNodes:', - upstreamNodes.map((n: any) => ({ - value: n.value, - children: n.children?.map((c: any) => c.value), - })), - ) if (!nodeEntry || !nodeEntry.children?.some((c: any) => c.value === cond.field[1])) { v_list.push(Promise.reject(t('workflow.variable.NoReferencing'))) }