diff --git a/packages/core/client/src/modules/blocks/BlockLinkageRuleProvider.tsx b/packages/core/client/src/modules/blocks/BlockLinkageRuleProvider.tsx index 7bb04fcbcd..40828f89bd 100644 --- a/packages/core/client/src/modules/blocks/BlockLinkageRuleProvider.tsx +++ b/packages/core/client/src/modules/blocks/BlockLinkageRuleProvider.tsx @@ -48,8 +48,6 @@ export const BlockLinkageRuleProvider = (props) => { useEffect(() => { if (shouldCalculateFormLinkage) { const id = uid(); - const disposes = []; - // 延迟执行,防止一开始获取到的 form.values 值是旧的 setTimeout(() => { form.addEffects(id, () => { @@ -77,9 +75,6 @@ export const BlockLinkageRuleProvider = (props) => { // 清理副作用 return () => { form.removeEffects(id); - disposes.forEach((dispose) => { - dispose(); - }); }; } }, [linkageRules, shouldCalculateFormLinkage]); diff --git a/packages/core/client/src/schema-component/antd/action/Action.tsx b/packages/core/client/src/schema-component/antd/action/Action.tsx index b41b765ed1..9075e40bbb 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.tsx @@ -12,10 +12,13 @@ import { observer, Schema, useField, useFieldSchema, useForm } from '@formily/re import { isPortalInBody } from '@nocobase/utils/client'; import { App, Button, Tooltip } from 'antd'; import classnames from 'classnames'; +import { isEqual } from 'lodash'; import debounce from 'lodash/debounce'; +import { reaction } from '@formily/reactive'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { ErrorBoundary } from 'react-error-boundary'; import { useTranslation } from 'react-i18next'; +import { uid } from '@formily/shared'; import { ErrorFallback, StablePopover, TabsContextProvider, useActionContext } from '../..'; import { useDesignable } from '../../'; import { useACLActionParamsContext } from '../../../acl'; @@ -29,7 +32,6 @@ import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { Icon } from '../../../icon'; import { TreeRecordProvider } from '../../../modules/blocks/data-blocks/table/TreeRecordProvider'; import { VariablePopupRecordProvider } from '../../../modules/variable/variablesProvider/VariablePopupRecordProvider'; -import { RecordProvider } from '../../../record-provider'; import { useLocalVariables, useVariables } from '../../../variables'; import { SortableItem } from '../../common'; import { useCompile, useComponent, useDesigner } from '../../hooks'; @@ -49,7 +51,11 @@ import { useGetAriaLabelOfAction } from './hooks/useGetAriaLabelOfAction'; import { ActionContextProps, ActionProps, ComposedAction } from './types'; import { linkageAction, setInitialActionState } from './utils'; import { NAMESPACE_UI_SCHEMA } from '../../../i18n/constant'; -import { BlockContext } from '../../../block-provider/BlockProvider'; +import { forEachLinkageRule } from '../../../schema-settings/LinkageRules/forEachLinkageRule'; +import { + getVariableValuesInCondition, + getVariableValuesInExpression, +} from '../../../schema-settings/LinkageRules/bindLinkageRulesToFiled'; // 这个要放到最下面,否则会导致前端单测失败 import { useApp } from '../../../application'; @@ -97,39 +103,62 @@ export const Action: ComposedAction = withDynamicSchemaProps( const { designable } = useDesignable(); const tarComponent = useComponent(component) || component; const variables = useVariables(); - const localVariables = useLocalVariables({ - currentForm: { values: recordData, readPretty: false } as any, - }); + const localVariables = useLocalVariables(); const { visibleWithURL, setVisibleWithURL } = usePopupUtils(); const { setSubmitted } = useActionContext(); const { getAriaLabel } = useGetAriaLabelOfAction(title); const parentRecordData = useCollectionParentRecordData(); const app = useApp(); const { getAllDataBlocks } = useAllDataBlocks(); + const form = useForm(); useEffect(() => { if (field.stateOfLinkageRules) { setInitialActionState(field); } - field.stateOfLinkageRules = {}; - linkageRules - .filter((k) => !k.disabled) - .forEach((v) => { - v.actions?.forEach((h) => { - linkageAction( - { - operator: h.operator, - field, - condition: v.condition, - variables, - localVariables, - conditionType: v.conditionType, - }, - app.jsonLogic, + const id = uid(); + const disposes = []; + // 如果不延迟执行,那么一开始获取到的 form.values 的值是旧的,会导致详情区块的联动规则出现一些问题 + setTimeout(() => { + form.addEffects(id, () => { + forEachLinkageRule(linkageRules, (action, rule) => { + disposes.push( + reaction( + () => { + // 获取条件中的变量值 + const variableValuesInCondition = getVariableValuesInCondition({ linkageRules, localVariables }); + const result = [variableValuesInCondition].map((item) => JSON.stringify(item)).join(','); + return result; + }, + () => { + console.log(action); + field.stateOfLinkageRules = {}; + linkageAction( + { + operator: action.operator, + field, + condition: rule.condition, + variables, + localVariables, + conditionType: rule.conditionType, + }, + app.jsonLogic, + ); + }, + { fireImmediately: true, equals: isEqual }, + ), ); }); }); - }, [field, linkageRules, localVariables, variables]); + }); + + return () => { + form.removeEffects(id); + disposes.forEach((dispose) => { + dispose(); + }); + }; + }, [linkageRules]); const handleMouseEnter = useCallback( (e) => { @@ -162,38 +191,36 @@ export const Action: ComposedAction = withDynamicSchemaProps( }, [onClick, fieldSchema, getAllDataBlocks]); return ( - - - + ); }), { displayName: 'Action' },