mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
feat: clean code
This commit is contained in:
parent
2f7660837d
commit
8ae3957578
@ -92,15 +92,33 @@ export function useFormEvents({ form }) {
|
||||
},
|
||||
},
|
||||
fn: (params) => {
|
||||
form.setFieldState(params.fieldName, params.fieldState);
|
||||
console.log('设置字段状态', params);
|
||||
// form.setFieldState(params.fieldName, params.fieldState);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'setValues',
|
||||
title: '设置表单值',
|
||||
description: '设置表单值',
|
||||
params: {
|
||||
name: {
|
||||
name: 'name',
|
||||
title: '字段名',
|
||||
type: 'string',
|
||||
description: '字段名',
|
||||
},
|
||||
value: {
|
||||
name: 'value',
|
||||
title: '字段值',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
fn: (params) => {
|
||||
form.setValues(params.values);
|
||||
console.log('设置表单值', params);
|
||||
form.setValues({
|
||||
...form.values,
|
||||
[params.name]: params.value,
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
@ -114,8 +132,8 @@ export function useFormEvents({ form }) {
|
||||
event: 'valueChange',
|
||||
},
|
||||
params: {
|
||||
// fieldName: payload?.props?.name,
|
||||
// fieldValue: payload?.inputValue,
|
||||
fieldName: payload?.props?.name,
|
||||
fieldValue: payload?.inputValue,
|
||||
values: form.values, // 用全量值代替某个值的改变,不太好传递动态的值类型
|
||||
},
|
||||
});
|
||||
|
@ -8,13 +8,17 @@
|
||||
*/
|
||||
|
||||
import { Plugin } from '../application/Plugin';
|
||||
import { EventActionSetting, EventSetting, PluginName } from './types';
|
||||
import { EventActionSetting, EventParamKey, EventSetting, SystemParamKey, StateParamKey, PluginName } from './types';
|
||||
import { EventSettingItem } from './EventSettingItem';
|
||||
import { uniqBy } from 'lodash';
|
||||
import { EventFlowProvider } from './EventFlowProvider';
|
||||
import { EventDefinition } from './types';
|
||||
import { ISchema } from '@formily/react';
|
||||
import { getPageSchema } from './utils';
|
||||
import { getConditionResult, getFieldValuesInCondition, getPageSchema } from './utils';
|
||||
import { conditionAnalyses } from '../schema-component/common/utils/uitls';
|
||||
import { VariableOption } from '../variables/types';
|
||||
import { VariablesContextType } from '../variables/types';
|
||||
import { parse, str2moment } from '@nocobase/utils/client';
|
||||
|
||||
export class EventFlowPlugin extends Plugin {
|
||||
static name = PluginName;
|
||||
@ -43,11 +47,16 @@ export class EventFlowPlugin extends Plugin {
|
||||
}
|
||||
|
||||
static isEqual(a: EventDefinition, b: EventDefinition) {
|
||||
return a.name === b.name && a.uid === b.uid && a.pageUid === b.pageUid;
|
||||
return a.name === b.name && a.pageUid === b.pageUid && a.blockUid === b.blockUid;
|
||||
}
|
||||
|
||||
static getEventUniqueKey(event: EventSetting['event']) {
|
||||
return `${event.definition}.${event.event}`;
|
||||
return `${event.pageUid}.${event.blockUid}.${event.definition}.${event.event}`;
|
||||
}
|
||||
|
||||
static parseEventUniqueKey(key: string) {
|
||||
const [pageUid, blockUid, definition, event] = key?.split('.') || [];
|
||||
return { pageUid, blockUid, definition, event };
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,20 +64,16 @@ export class EventFlowPlugin extends Plugin {
|
||||
* @param definition 事件定义
|
||||
* @param fieldSchema 字段对应schema
|
||||
*/
|
||||
define(definition: EventDefinition | EventDefinition[], fieldSchema?: ISchema) {
|
||||
const uid = fieldSchema?.['x-uid'];
|
||||
const pageSchema = getPageSchema(fieldSchema);
|
||||
const pageUid = pageSchema?.['x-uid'];
|
||||
if (!definition) {
|
||||
return;
|
||||
}
|
||||
const definitions = Array.isArray(definition) ? definition : [definition];
|
||||
define(definitions: EventDefinition[]) {
|
||||
definitions.forEach((item) => {
|
||||
item.uid = uid;
|
||||
item.pageUid = pageUid;
|
||||
const exist = this.definitions.find((def) => EventFlowPlugin.isEqual(def, item));
|
||||
if (exist) {
|
||||
Object.assign(exist, item);
|
||||
} else {
|
||||
this.definitions.push(item);
|
||||
}
|
||||
});
|
||||
this.definitions.push(...definitions);
|
||||
this.definitions = uniqBy(this.definitions, (item) => item.name + item.uid);
|
||||
console.log('definitions', this.definitions);
|
||||
}
|
||||
// 移除定义事件
|
||||
// removeDefinition(definition: EventDefinition | EventDefinition[]) {
|
||||
@ -89,28 +94,62 @@ export class EventFlowPlugin extends Plugin {
|
||||
* @param p.event 事件
|
||||
* @param p.params 事件上报的参数
|
||||
*/
|
||||
async emit(p: { event: EventSetting['event']; params?: any }) {
|
||||
console.log('emit', p);
|
||||
const event = this.events.get(EventFlowPlugin.getEventUniqueKey(p.event));
|
||||
if (event) {
|
||||
const condition = event.condition;
|
||||
const isCondition = false;
|
||||
// todo 条件判断
|
||||
if (!isCondition) {
|
||||
return;
|
||||
}
|
||||
event.actions.forEach((act: EventActionSetting) => {
|
||||
const definition = this.definitions.find((def) => def.name === act.definition);
|
||||
const action = definition?.actions?.find((action) => action.name === act.action);
|
||||
async emit(p: {
|
||||
event: EventSetting['event'];
|
||||
params?: any;
|
||||
variables: VariablesContextType;
|
||||
localVariables: VariableOption[];
|
||||
}) {
|
||||
const rules = this.events.get(EventFlowPlugin.getEventUniqueKey(p.event))?.rules;
|
||||
const getParsedValue = (expression: string) => {
|
||||
const template = parse(expression);
|
||||
return template(p.variables);
|
||||
};
|
||||
if (rules) {
|
||||
for (const rule of rules) {
|
||||
const condition = rule.condition;
|
||||
const conditionValues = {
|
||||
[EventParamKey]: p.params,
|
||||
[StateParamKey]: {},
|
||||
[SystemParamKey]: {},
|
||||
};
|
||||
console.log('conditionValues', condition, p, conditionValues);
|
||||
// const isConditionPass = getConditionResult({ condition, values: conditionValues });
|
||||
const isConditionPass = await conditionAnalyses({
|
||||
ruleGroup: condition,
|
||||
variables: p.variables,
|
||||
localVariables: [
|
||||
...p.localVariables,
|
||||
{
|
||||
name: '$eventValues',
|
||||
ctx: conditionValues,
|
||||
},
|
||||
],
|
||||
variableNameOfLeftCondition: '$eventValues',
|
||||
});
|
||||
console.log('isConditionPass', isConditionPass);
|
||||
if (isConditionPass) {
|
||||
rule.actions.forEach((act: EventActionSetting) => {
|
||||
const definition = this.definitions.find((def) => def.name === act.action.definition);
|
||||
const action = definition?.actions?.find((action) => action.name === act.action.action);
|
||||
// todo 获取action的参数
|
||||
const actionParams = act.params;
|
||||
const actionParams = {};
|
||||
act.params?.forEach((param) => {
|
||||
actionParams[param.name] = getParsedValue(param.value);
|
||||
});
|
||||
console.log('执行动作3', act, action, actionParams);
|
||||
if (action) {
|
||||
action.fn(actionParams);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
on(event: EventSetting) {
|
||||
if (!event.event) {
|
||||
return;
|
||||
}
|
||||
this.events.set(EventFlowPlugin.getEventUniqueKey(event.event), event);
|
||||
}
|
||||
}
|
||||
|
@ -12,10 +12,14 @@ import { EventActionSetting } from '../../types';
|
||||
import { useEvent } from '../../hooks/useEvent';
|
||||
import React from 'react';
|
||||
|
||||
export function ActionParamSelect(props: { action: EventActionSetting }) {
|
||||
export function ActionParamSelect(props: { action: EventActionSetting['action'] }) {
|
||||
const { action, ...rest } = props;
|
||||
const { definitions } = useEvent();
|
||||
const params = definitions.find((x) => x.uid === action?.uid)?.actions?.find((x) => x.name === action.event)?.params;
|
||||
const definition = definitions.find(
|
||||
(x) => x.name === action?.definition && x.blockUid === action?.blockUid && x.pageUid === action?.pageUid,
|
||||
);
|
||||
const actionDef = definition?.actions?.find((x) => x.name === action.action);
|
||||
const params = actionDef?.params;
|
||||
const options = Object.keys(params || {}).map((key) => ({
|
||||
name: key,
|
||||
label: params[key]?.title,
|
||||
|
@ -9,33 +9,52 @@
|
||||
|
||||
import { observer } from '@formily/react';
|
||||
import { Cascader } from 'antd';
|
||||
import React from 'react';
|
||||
import { useActionOptions } from '../hooks/useActionOptions';
|
||||
import React, { useMemo } from 'react';
|
||||
import { EventActionSetting } from '../../types';
|
||||
import { useEvent } from '../../hooks/useEvent';
|
||||
import { useControllableValue } from 'ahooks';
|
||||
|
||||
export const ActionSelect = observer((props: any) => {
|
||||
const options = useActionOptions();
|
||||
const { definitions } = useEvent();
|
||||
const [state, setState] = useControllableValue<EventActionSetting['action']>(props, {
|
||||
defaultValue: undefined,
|
||||
});
|
||||
|
||||
let treeData = definitions?.map((definition) => ({
|
||||
value: `${definition.name}.${definition.blockUid}`,
|
||||
label: definition.title + '-' + definition.blockUid,
|
||||
children:
|
||||
definition?.actions?.map((action) => ({
|
||||
value: `${definition.pageUid || ''}.${definition.blockUid || ''}.${definition.name}.${action.name}`,
|
||||
label: action.title,
|
||||
})) || [],
|
||||
}));
|
||||
treeData = treeData?.filter((item) => item.children.length > 0);
|
||||
|
||||
const { onChange, value, ...rest } = props;
|
||||
const _onChange = (value: any, selectedOptions: any) => {
|
||||
const v = value[1];
|
||||
if (v) {
|
||||
const res: EventActionSetting = {
|
||||
definition: v.split('.')[0],
|
||||
event: v.split('.')[1],
|
||||
uid: v.split('.')[2],
|
||||
};
|
||||
onChange?.(res);
|
||||
} else {
|
||||
onChange?.(undefined);
|
||||
}
|
||||
};
|
||||
const _value = value ? [value.definition, `${value.definition}.${value.event}.${value.uid}`] : [];
|
||||
|
||||
const selectedAction = useMemo(() => {
|
||||
if (!state) return undefined;
|
||||
return [
|
||||
`${state.definition}.${state.blockUid}`,
|
||||
`${state.pageUid || ''}.${state.blockUid || ''}.${state.definition}.${state.action}`,
|
||||
];
|
||||
}, [state]);
|
||||
|
||||
return (
|
||||
<Cascader
|
||||
placeholder="请选择动作"
|
||||
options={options}
|
||||
onChange={_onChange}
|
||||
value={_value}
|
||||
options={treeData}
|
||||
onChange={(value: any, selectedOptions: any) => {
|
||||
const v = value[1];
|
||||
if (v) {
|
||||
const [pageUid, blockUid, definition, action] = v.split('.');
|
||||
setState({ pageUid, blockUid, definition, action });
|
||||
} else {
|
||||
setState(undefined);
|
||||
}
|
||||
}}
|
||||
value={selectedAction}
|
||||
style={{ minWidth: 300 }}
|
||||
{...rest}
|
||||
/>
|
||||
|
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import React, { createContext } from 'react';
|
||||
|
||||
export const eventContext = createContext<{ pageUid: string }>({ pageUid: '' });
|
||||
|
||||
export const EventProvider = (props: { pageUid: string; children: React.ReactNode }) => {
|
||||
const { pageUid } = props;
|
||||
return <eventContext.Provider value={{ pageUid }}>{props.children}</eventContext.Provider>;
|
||||
};
|
@ -10,7 +10,7 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { useControllableValue } from 'ahooks';
|
||||
import { Card, Space, TreeSelect } from 'antd';
|
||||
import { EventDefinition, EventSetting } from '../types';
|
||||
import { EventDefinition, EventSetting } from '../../types';
|
||||
|
||||
export default function EventSelect(props: {
|
||||
definitions?: EventDefinition[];
|
||||
@ -25,11 +25,11 @@ export default function EventSelect(props: {
|
||||
|
||||
let treeData = definitions?.map((module) => ({
|
||||
value: module.name,
|
||||
title: module.title + ' - ' + module.uid,
|
||||
title: module.title + ' - ' + module.blockUid,
|
||||
selectable: false,
|
||||
children:
|
||||
module?.events?.map((event) => ({
|
||||
value: `${module.name}.${event.name}${module.uid ? `.${module.uid}` : ''}`,
|
||||
value: `${module.pageUid || ''}.${module.blockUid || ''}.${module.name}.${event.name}`,
|
||||
title: event.title,
|
||||
})) || [],
|
||||
}));
|
||||
@ -37,7 +37,7 @@ export default function EventSelect(props: {
|
||||
|
||||
const selectedEvent = useMemo(() => {
|
||||
if (!state) return undefined;
|
||||
return `${state.definition}.${state.event}${state.uid ? `.${state.uid}` : ''}`;
|
||||
return `${state.pageUid || ''}.${state.blockUid || ''}.${state.definition}.${state.event}`;
|
||||
}, [state]);
|
||||
|
||||
return (
|
||||
@ -48,12 +48,16 @@ export default function EventSelect(props: {
|
||||
allowClear
|
||||
treeDefaultExpandAll
|
||||
onChange={(value) => {
|
||||
console.log('value', value);
|
||||
const [definition, event, uid] = (value as any).split('.');
|
||||
if (!value) {
|
||||
setState(undefined);
|
||||
return;
|
||||
}
|
||||
const [pageUid, blockUid, definition, event] = value?.split('.') || [];
|
||||
setState({
|
||||
pageUid,
|
||||
blockUid,
|
||||
definition,
|
||||
event,
|
||||
uid,
|
||||
});
|
||||
}}
|
||||
treeData={treeData}
|
@ -1,27 +0,0 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { useEvent } from '../../hooks/useEvent';
|
||||
|
||||
export function useActionOptions() {
|
||||
const { definitions } = useEvent();
|
||||
|
||||
let treeData = definitions?.map((module) => ({
|
||||
value: module.name,
|
||||
label: module.title + ' - ' + module.uid,
|
||||
children:
|
||||
module?.actions?.map((event) => ({
|
||||
value: `${module.name}.${event.name}${module.uid ? `.${module.uid}` : ''}`,
|
||||
label: event.title,
|
||||
})) || [],
|
||||
}));
|
||||
treeData = treeData?.filter((item) => item.children.length > 0);
|
||||
|
||||
return treeData;
|
||||
}
|
@ -9,24 +9,26 @@
|
||||
|
||||
import { useDataSourceManager } from '../../../data-source/data-source';
|
||||
import { useEvent } from '../../hooks/useEvent';
|
||||
import { EventParam, EventSetting, EventDefinition } from '../../types';
|
||||
import { EventParam, EventSetting, EventDefinition, EventParamKey, StateParamKey, SystemParamKey } from '../../types';
|
||||
|
||||
const useCurrentEventParams: (event?: EventSetting['event']) => {
|
||||
[key: string]: EventParam;
|
||||
} = (event) => {
|
||||
const useCurrentEventParams = (event?: EventSetting['event']) => {
|
||||
const { definitions } = useEvent();
|
||||
const definition = definitions?.find((d) => d.name === event?.definition && d.uid === event.uid);
|
||||
const definition = definitions?.find(
|
||||
(d) => d.name === event?.definition && d.pageUid === event.pageUid && d.blockUid === event.blockUid,
|
||||
);
|
||||
const eventParams = definition?.events?.find((e) => e.name === event?.event)?.params;
|
||||
return eventParams;
|
||||
};
|
||||
|
||||
const useStateDefine = ({ definitions }: { definitions: EventDefinition[] }) => {
|
||||
const stateDefine = definitions.filter((item) => item.uid && item.states);
|
||||
const useStateDefine = () => {
|
||||
const { definitions } = useEvent();
|
||||
const stateDefineOptions = {};
|
||||
stateDefine.forEach((definition) => {
|
||||
stateDefineOptions[definition.uid] = {
|
||||
name: definition.uid,
|
||||
title: `${definition.title}-${definition.uid}`,
|
||||
definitions
|
||||
.filter((item) => item.states && item.blockUid) // 必须为区块的数据
|
||||
.forEach((definition) => {
|
||||
stateDefineOptions[definition.blockUid] = {
|
||||
name: definition.blockUid,
|
||||
title: `${definition.title}-${definition.blockUid}`,
|
||||
type: 'object',
|
||||
properties: definition.states,
|
||||
};
|
||||
@ -36,29 +38,29 @@ const useStateDefine = ({ definitions }: { definitions: EventDefinition[] }) =>
|
||||
};
|
||||
|
||||
export const useFilterOptions = (event?: EventSetting['event']) => {
|
||||
const currentEventParamsDefine = useCurrentEventParams(event);
|
||||
const { definitions } = useEvent();
|
||||
const { stateDefineOptions } = useStateDefine({ definitions });
|
||||
const currentEventParamsDefine: EventParam[] = useCurrentEventParams(event);
|
||||
const { stateDefineOptions } = useStateDefine();
|
||||
console.log('useFilterOptions', event, currentEventParamsDefine, stateDefineOptions);
|
||||
|
||||
const options: EventParam[] = [
|
||||
{
|
||||
name: '_eventParams',
|
||||
name: EventParamKey,
|
||||
title: '事件参数',
|
||||
type: 'object',
|
||||
properties: currentEventParamsDefine,
|
||||
},
|
||||
{
|
||||
name: '_state',
|
||||
name: StateParamKey,
|
||||
title: '组件数据',
|
||||
type: 'object',
|
||||
properties: stateDefineOptions,
|
||||
},
|
||||
// {
|
||||
// name: '_system',
|
||||
// title: '系统参数',
|
||||
// type: 'object',
|
||||
// properties: {},
|
||||
// },
|
||||
{
|
||||
name: SystemParamKey,
|
||||
title: '应用数据',
|
||||
type: 'object',
|
||||
properties: {},
|
||||
},
|
||||
];
|
||||
const dm = useDataSourceManager();
|
||||
|
||||
|
@ -21,13 +21,14 @@ import {
|
||||
useFormBlockType,
|
||||
useRecord,
|
||||
Filter,
|
||||
getPageSchema,
|
||||
} from '@nocobase/client';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { ISchema, useField } from '@formily/react';
|
||||
import { SchemaSettingsKey, useEvent } from '..';
|
||||
import { useFieldSchema } from '@formily/react';
|
||||
import { useLinkageCollectionFieldOptions } from './ActionsSetting/action-hooks';
|
||||
import EventSelect from './EventSelect';
|
||||
import EventSelect from './components/EventSelect';
|
||||
import { ArrayCollapse } from './components/LinkageHeader';
|
||||
import { css } from '@emotion/css';
|
||||
import { FormItem, FormLayout } from '@formily/antd-v5';
|
||||
@ -37,6 +38,7 @@ import { ActionParamSelect } from './components/ActionParamSelect';
|
||||
import ConditionSelect from './components/ConditionSelect';
|
||||
import { Space } from 'antd';
|
||||
import { ActionParamValueInput } from './components/ActionParamValueInput';
|
||||
import { EventProvider } from './components/EventProvider';
|
||||
|
||||
// packages/core/client/src/schema-settings/SchemaSettings.tsx
|
||||
export const EventSettingItem = (props) => {
|
||||
@ -47,6 +49,7 @@ export const EventSettingItem = (props) => {
|
||||
const { definitions, register } = useEvent();
|
||||
const { dn } = useDesignable();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const pageUid = getPageSchema(fieldSchema)?.['x-uid'];
|
||||
|
||||
return (
|
||||
<SchemaSettingsModalItem
|
||||
@ -80,7 +83,10 @@ export const EventSettingItem = (props) => {
|
||||
type: 'array',
|
||||
// default: defaultValues,
|
||||
'x-component': 'ArrayCollapse',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-decorator': EventProvider,
|
||||
'x-decorator-props': {
|
||||
pageUid,
|
||||
},
|
||||
'x-component-props': {
|
||||
accordion: true,
|
||||
titleRender: (item: any, index: number) => {
|
||||
@ -101,6 +107,7 @@ export const EventSettingItem = (props) => {
|
||||
definitions,
|
||||
className: css`
|
||||
margin-bottom: 12px;
|
||||
width: 100%;
|
||||
`,
|
||||
},
|
||||
},
|
||||
@ -109,23 +116,6 @@ export const EventSettingItem = (props) => {
|
||||
'x-content': '{{ t("执行规则") }}',
|
||||
},
|
||||
actionsBlock: rulesSchema,
|
||||
// actionsBlock: {
|
||||
// type: 'void',
|
||||
// 'x-component': ActionsSetting,
|
||||
// 'x-use-component-props': () => {
|
||||
// return {
|
||||
// options,
|
||||
// linkageOptions,
|
||||
// category: 'default',
|
||||
// elementType: 'field',
|
||||
// collectionName,
|
||||
// // form,
|
||||
// variables,
|
||||
// localVariables,
|
||||
// formBlockType,
|
||||
// };
|
||||
// },
|
||||
// },
|
||||
remove: {
|
||||
type: 'void',
|
||||
'x-component': 'ArrayCollapse.Remove',
|
||||
|
@ -9,20 +9,32 @@
|
||||
|
||||
import { EventDefinition, EventSetting } from '../types';
|
||||
import { useFieldSchema } from '@formily/react';
|
||||
import { getPageSchema, useApp, usePlugin, useSchemaSettings } from '@nocobase/client';
|
||||
import React from 'react';
|
||||
import { getPageSchema, useApp, useLocalVariables, usePlugin, useVariables, useSchemaSettings } from '@nocobase/client';
|
||||
import React, { useContext } from 'react';
|
||||
import { ISchema, useField } from '@formily/react';
|
||||
import { EventFlowPlugin } from '..';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { eventContext } from '../EventSettingItem/components/EventProvider';
|
||||
|
||||
export const useEvent = () => {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const uid = fieldSchema?.['x-uid'];
|
||||
const pageUid = getPageSchema(fieldSchema)?.['x-uid'];
|
||||
const context = useContext(eventContext);
|
||||
const pageUid = context.pageUid || getPageSchema(fieldSchema)?.['x-uid'];
|
||||
const blockUid = fieldSchema?.['x-uid'];
|
||||
const eventFlowPlugin: EventFlowPlugin = usePlugin(EventFlowPlugin.name) as any;
|
||||
const variables = useVariables();
|
||||
const localVariables = useLocalVariables({ currentForm: null });
|
||||
|
||||
const define = useMemoizedFn((definition: EventDefinition[] | EventDefinition) => {
|
||||
eventFlowPlugin?.define(definition, fieldSchema);
|
||||
if (!definition) {
|
||||
return;
|
||||
}
|
||||
const definitions = Array.isArray(definition) ? definition : [definition];
|
||||
definitions.forEach((item) => {
|
||||
item.pageUid = pageUid;
|
||||
item.blockUid = blockUid;
|
||||
});
|
||||
eventFlowPlugin?.define(definitions);
|
||||
});
|
||||
|
||||
const register = useMemoizedFn((events: EventSetting[]) => {
|
||||
@ -33,14 +45,19 @@ export const useEvent = () => {
|
||||
await eventFlowPlugin?.emit({
|
||||
event: {
|
||||
...p.event,
|
||||
uid: uid,
|
||||
pageUid,
|
||||
blockUid,
|
||||
},
|
||||
params: p.params,
|
||||
variables,
|
||||
localVariables,
|
||||
});
|
||||
});
|
||||
|
||||
console.log('event pageUid', pageUid);
|
||||
|
||||
return {
|
||||
definitions: eventFlowPlugin?.definitions.filter((item) => item.pageUid === pageUid || !item.pageUid || !pageUid),
|
||||
definitions: eventFlowPlugin?.definitions.filter((item) => item.pageUid === pageUid || !item.pageUid),
|
||||
// 定义事件
|
||||
define,
|
||||
// 移除事件
|
||||
|
@ -10,7 +10,9 @@
|
||||
export const PluginName = 'event';
|
||||
export const SchemaSettingsKey = 'x-event-settings';
|
||||
export const SchemaDefinitionsKey = 'x-event-definitions';
|
||||
|
||||
export const EventParamKey = '$eventParams';
|
||||
export const StateParamKey = '_state';
|
||||
export const SystemParamKey = '_system';
|
||||
export interface EventParam {
|
||||
name?: string; // 在item 情况下没有name https://json-schema.org/understanding-json-schema/reference/array
|
||||
title?: string;
|
||||
@ -26,41 +28,52 @@ export interface EventParam {
|
||||
|
||||
/** 事件动作 */
|
||||
export interface EventAction {
|
||||
/** 动作名称 英文,全局唯一 */
|
||||
name: string;
|
||||
/** 动作标题 */
|
||||
title: string;
|
||||
/** 动作描述 */
|
||||
description?: string;
|
||||
params?: {
|
||||
[key: string]: EventParam;
|
||||
};
|
||||
/** 动作参数 */
|
||||
params?: EventParam[];
|
||||
/** 动作返回值 */
|
||||
return?: EventParam;
|
||||
/** 动作执行函数 */
|
||||
fn: (params?: any) => void;
|
||||
}
|
||||
|
||||
/** 事件事件 */
|
||||
/** 具体事件定义 */
|
||||
export interface EventEvent {
|
||||
/** 事件名称 英文,全局唯一 */
|
||||
name: string;
|
||||
/** 事件标题 */
|
||||
title: string;
|
||||
uid?: string;
|
||||
/** 事件描述 */
|
||||
description?: string;
|
||||
params?: {
|
||||
[key: string]: EventParam;
|
||||
};
|
||||
value?: any;
|
||||
/** 事件参数, 可以配置多个参数 */
|
||||
params?: EventParam[];
|
||||
}
|
||||
|
||||
/** 事件定义 */
|
||||
/** 事件模块定义 */
|
||||
export interface EventDefinition {
|
||||
/** 定义名称 英文,全局唯一 */
|
||||
name: string;
|
||||
/** 标识同一类型组件的不同实例 */
|
||||
uid?: string;
|
||||
/** 标识所属页面 */
|
||||
/** 定义所属页面uid, 系统级别定义该字段为 'app' */
|
||||
pageUid?: string;
|
||||
/** 定义所属区块uid,系统级别定义该字段为空 */
|
||||
blockUid?: string;
|
||||
/** 定义标题 */
|
||||
title: string;
|
||||
/** 定义描述 */
|
||||
description?: string;
|
||||
/** 事件 */
|
||||
events?: EventEvent[];
|
||||
/** 动作 */
|
||||
actions?: EventAction[];
|
||||
/** 区块内暴露的数据 */
|
||||
states?: {
|
||||
[key: string]: EventParam;
|
||||
};
|
||||
actions?: EventAction[];
|
||||
}
|
||||
|
||||
/** 事件设置 */
|
||||
@ -68,17 +81,23 @@ export interface EventSetting {
|
||||
event: {
|
||||
definition: string;
|
||||
event: string;
|
||||
uid?: string;
|
||||
pageUid?: string;
|
||||
blockUid?: string;
|
||||
};
|
||||
/** 标识同一类型组件的不同实例 */
|
||||
// uid?: string;
|
||||
rules?: Array<{
|
||||
condition: string;
|
||||
actions: Array<EventActionSetting>;
|
||||
}>;
|
||||
/** 标识同一类型组件的不同实例 */
|
||||
// uid?: string;
|
||||
}
|
||||
export interface EventActionSetting {
|
||||
action: {
|
||||
definition: string;
|
||||
action: string;
|
||||
uid?: string;
|
||||
pageUid?: string;
|
||||
blockUid?: string;
|
||||
};
|
||||
params?: Array<EventActionSettingParams>;
|
||||
}
|
||||
export interface EventActionSettingParams {
|
||||
|
@ -8,6 +8,8 @@
|
||||
*/
|
||||
|
||||
import { ISchema } from '@formily/react';
|
||||
import { every, findIndex, some } from 'lodash';
|
||||
import { getValuesByPath, uid } from '@nocobase/utils/client';
|
||||
|
||||
export const getPageSchema = (schema: any) => {
|
||||
if (schema?.['x-component'] === 'Page') {
|
||||
@ -18,3 +20,79 @@ export const getPageSchema = (schema: any) => {
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
function getAllKeys(obj) {
|
||||
const keys = [];
|
||||
function traverse(o) {
|
||||
Object.keys(o)
|
||||
.sort()
|
||||
.forEach(function (key) {
|
||||
keys.push(key);
|
||||
if (o[key] && typeof o[key] === 'object') {
|
||||
traverse(o[key]);
|
||||
}
|
||||
});
|
||||
}
|
||||
traverse(obj);
|
||||
return keys;
|
||||
}
|
||||
|
||||
const getTargetField = (obj) => {
|
||||
const keys = getAllKeys(obj);
|
||||
const index = findIndex(keys, (key, index, keys) => {
|
||||
if (key.includes('$') && index > 0) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
const result = keys.slice(0, index);
|
||||
return result;
|
||||
};
|
||||
|
||||
export function getFieldValuesInCondition({ linkageRules, formValues }) {
|
||||
return linkageRules.map((rule) => {
|
||||
const run = (condition) => {
|
||||
const type = Object.keys(condition)[0] || '$and';
|
||||
const conditions = condition[type];
|
||||
|
||||
return conditions
|
||||
.map((condition) => {
|
||||
if ('$and' in condition || '$or' in condition) {
|
||||
return run(condition);
|
||||
}
|
||||
|
||||
const path = getTargetField(condition).join('.');
|
||||
return getValuesByPath(formValues, path);
|
||||
})
|
||||
.filter(Boolean);
|
||||
};
|
||||
|
||||
return run(rule.condition);
|
||||
});
|
||||
}
|
||||
|
||||
export function getConditionResult({ condition, values }) {
|
||||
const run = (condition) => {
|
||||
const type = Object.keys(condition)[0] || '$and';
|
||||
const conditions = condition[type];
|
||||
|
||||
const ress = conditions.map((condition) => {
|
||||
if ('$and' in condition || '$or' in condition) {
|
||||
return run(condition);
|
||||
}
|
||||
|
||||
const path = getTargetField(condition).join('.');
|
||||
console.log('path', path, values);
|
||||
const v = getValuesByPath(values, path);
|
||||
console.log('v', v);
|
||||
return v;
|
||||
});
|
||||
if (type === '$and') {
|
||||
return every(ress, Boolean);
|
||||
}
|
||||
if (type === '$or') {
|
||||
return some(ress, Boolean);
|
||||
}
|
||||
};
|
||||
|
||||
return run(condition);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user