100011797 3 gadi atpakaļ
vecāks
revīzija
d041c95851

+ 78 - 40
src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx

@@ -6,8 +6,8 @@ import './index.less';
 import TriggerAlarm from '../TriggerAlarm';
 import { AddButton } from '@/pages/rule-engine/Scene/Save/components/Buttons';
 import FilterCondition from './FilterCondition';
-import { set } from 'lodash';
-import { Popconfirm } from 'antd';
+import { isArray, set } from 'lodash';
+import { Form, Popconfirm } from 'antd';
 
 export enum ParallelEnum {
   'parallel' = 'parallel',
@@ -306,45 +306,83 @@ export default (props: ItemProps) => {
         </Popconfirm>
       </div>
       {props.parallel ? null : (
-        <FilterCondition
-          action={props.name}
-          branchGroup={props.branchGroup}
-          thenName={props.thenName}
-          data={props.data.terms?.[0]}
-          label={props.data.options?.terms}
-          onAdd={() => {
-            let _data = props.data;
-            if (!_data.terms) {
-              _data = {
-                ..._data,
-                terms: [{}],
-              };
+        <Form.Item
+          name={[
+            'branches',
+            props.thenName,
+            'then',
+            props.branchGroup || 0,
+            'actions',
+            props.name,
+            'terms',
+          ]}
+          rules={[
+            {
+              validator(_, v) {
+                if (v) {
+                  if (!v.column) {
+                    return Promise.reject(new Error('请选择参数'));
+                  }
+
+                  if (!v.termType) {
+                    return Promise.reject(new Error('请选择操作符'));
+                  }
+
+                  if (!v.value) {
+                    return Promise.reject(new Error('请选择或输入参数值'));
+                  } else {
+                    if (isArray(v.value.value) && v.value.value.some((_v: any) => !_v)) {
+                      return Promise.reject(new Error('请选择或输入参数值'));
+                    } else if (!v.value.value) {
+                      return Promise.reject(new Error('请选择或输入参数值'));
+                    }
+                  }
+                }
+                return Promise.resolve();
+              },
+            },
+          ]}
+        >
+          <FilterCondition
+            action={props.name}
+            branchGroup={props.branchGroup}
+            thenName={props.thenName}
+            data={props.data.terms?.[0]}
+            label={props.data.options?.terms}
+            onAdd={() => {
+              let _data = props.data;
+              if (!_data.terms) {
+                _data = {
+                  ..._data,
+                  terms: [{}],
+                };
+                cacheValueRef.current = _data;
+                props.onUpdate(_data, op);
+              }
+            }}
+            onChange={(termsData) => {
+              const _data = props.data;
+              set(_data, 'terms', [termsData]);
               cacheValueRef.current = _data;
-              props.onUpdate(_data, op);
-            }
-          }}
-          onChange={(termsData) => {
-            const _data = props.data;
-            set(_data, 'terms', [termsData]);
-            cacheValueRef.current = _data;
-            props.onUpdate(_data, {
-              ...op,
-            });
-          }}
-          onLabelChange={(lb) => {
-            props.onUpdate(cacheValueRef.current, {
-              ...op,
-              terms: lb,
-            });
-          }}
-          onDelete={() => {
-            const _data = props.data;
-            if (_data.terms) {
-              delete _data.terms;
-              props.onUpdate(_data, op);
-            }
-          }}
-        />
+              props.onUpdate(_data, {
+                ...op,
+              });
+            }}
+            onLabelChange={(lb) => {
+              props.onUpdate(cacheValueRef.current, {
+                ...op,
+                terms: lb,
+              });
+            }}
+            onDelete={() => {
+              const _data = props.data;
+              if (_data.terms) {
+                delete _data.terms;
+                props.onUpdate(_data, op);
+              }
+            }}
+          />
+        </Form.Item>
       )}
       {visible && (
         <Modal

+ 0 - 2
src/pages/rule-engine/Scene/Save/action/ListItem/index.less

@@ -87,8 +87,6 @@
 }
 
 .filter-condition-warp {
-  margin-bottom: 16px;
-
   .filter-condition-content {
     position: relative;
     padding: 16px;

+ 9 - 2
src/pages/rule-engine/Scene/Save/action/index.tsx

@@ -7,7 +7,7 @@ import { Observer } from '@formily/react';
 import { get } from 'lodash';
 import type { ShakeLimitType, BranchesThen } from '../../typings';
 import { randomString } from '@/utils/util';
-import { useEffect, useState } from 'react';
+import { useEffect, useRef, useState } from 'react';
 
 const { Panel } = Collapse;
 
@@ -17,14 +17,16 @@ interface ActionsProps {
   thenOptions: BranchesThen[];
   onAdd: (data: BranchesThen) => void;
   onUpdate: (data: BranchesThen, type: boolean) => void;
-  onChange?: (data: BranchesThen) => void;
+  onChange?: (data?: BranchesThen[]) => void;
 }
 
 export default (props: ActionsProps) => {
   const [parallelArray, setParallelArray] = useState<BranchesThen[]>([]); // 并行行
   const [serialArray, setSerialArray] = useState<BranchesThen[]>([]); // 串行
   const [activeKeys, setActiveKey] = useState<any | any[]>(['1']);
+
   const [lock, setLock] = useState(false);
+  const firstLockRef = useRef(true);
 
   useEffect(() => {
     const parallelArr = props.thenOptions.filter((item) => item.parallel);
@@ -35,6 +37,11 @@ export default (props: ActionsProps) => {
       setActiveKey(['2']);
       setLock(true);
     }
+    if (!firstLockRef.current) {
+      props.onChange?.(props.thenOptions);
+    } else {
+      firstLockRef.current = false;
+    }
   }, [props.thenOptions]);
 
   return (

+ 1 - 2
src/pages/rule-engine/Scene/Save/device/index.tsx

@@ -110,14 +110,13 @@ export default observer((props: Props) => {
           }}
         </Observer>
       </div>
-      <Terms />
+      <Terms form={props.form} />
       {visible && (
         <AddModel
           value={FormModel.current.trigger?.device || defaultDeviceValue}
           options={FormModel.current.options?.trigger}
           onSave={(data, options) => {
             setVisible(false);
-            console.log('FormModel.current.options', data);
             set(FormModel.current, ['options', 'trigger'], options);
             set(FormModel.current, ['trigger', 'device'], data);
             props.form.setFieldValue('device', data);

+ 7 - 6
src/pages/rule-engine/Scene/Save/index.tsx

@@ -117,23 +117,23 @@ export default observer(() => {
     if (id) {
       service.detail(id).then((resp) => {
         if (resp.status === 200) {
+          const _triggerType = resp.result.triggerType;
           let branches = resp.result.branches;
           if (!branches) {
-            branches = defaultBranches;
-            if (resp.result.triggerType === 'device') {
+            branches = cloneDeep(defaultBranches);
+            if (_triggerType === 'device') {
               branches.push(null);
             }
           } else {
             const branchesLength = branches.length;
             if (
-              resp.result.triggerType === 'device' &&
+              _triggerType === 'device' &&
               ((branchesLength === 1 && !!branches[0]?.when?.length) || // 有一组数据并且when有值
                 (branchesLength > 1 && !branches[branchesLength - 1]?.when?.length)) // 有多组否则数据,并且最后一组when有值
             ) {
               branches.push(null);
             }
           }
-
           FormModel.current = {
             ...resp.result,
           };
@@ -142,8 +142,9 @@ export default observer(() => {
           FormModel.current.trigger = resp.result.trigger || {};
           FormModel.current.branches = newBranches;
           form.setFieldValue('description', resp.result.description);
-          if (['device', 'timer'].includes(resp.result.triggerType)) {
-            form.setFieldValue(resp.result.triggerType, resp.result.trigger);
+
+          if (['device', 'timer'].includes(_triggerType)) {
+            form.setFieldValue(_triggerType, resp.result.trigger[_triggerType]);
           }
           form.setFieldValue('branches', newBranches);
         }

+ 3 - 12
src/pages/rule-engine/Scene/Save/manual/index.tsx

@@ -1,12 +1,9 @@
 import Action from '../action';
 import { Observer } from '@formily/react';
 import { FormModel } from '@/pages/rule-engine/Scene/Save';
-import { Form, FormInstance } from 'antd';
-interface Props {
-  form: FormInstance;
-}
+import { Form } from 'antd';
 
-export default (props: Props) => {
+export default () => {
   return (
     <div>
       <Observer>
@@ -16,7 +13,7 @@ export default (props: Props) => {
             rules={[
               {
                 validator(_, v) {
-                  if (v && !v.length) {
+                  if (!v || (v && !v.length)) {
                     return Promise.reject('至少配置一个执行动作');
                   }
                   return Promise.resolve();
@@ -31,8 +28,6 @@ export default (props: Props) => {
                 if (FormModel.current.branches && data) {
                   const newThen = [...FormModel.current.branches[0].then, data];
                   FormModel.current.branches[0].then = newThen;
-                  props.form.setFieldValue(['branches', 0, 'then'], newThen);
-                  props.form.validateFields(['branches', 0, 'then']);
                 }
               }}
               onUpdate={(data, type) => {
@@ -45,10 +40,6 @@ export default (props: Props) => {
                   } else {
                     FormModel.current.branches![0].then = [];
                   }
-                  props.form.setFieldValue(
-                    ['branches', 0, 'then'],
-                    FormModel.current.branches![0].then,
-                  );
                 }
               }}
             />

+ 41 - 23
src/pages/rule-engine/Scene/Save/terms/branchItem.tsx

@@ -8,7 +8,7 @@ import Actions from '@/pages/rule-engine/Scene/Save/action';
 import classNames from 'classnames';
 import { set } from 'lodash';
 import { Store } from 'jetlinks-store';
-import { Popconfirm } from 'antd';
+import { Form, FormInstance, Popconfirm } from 'antd';
 
 interface BranchesItemProps {
   name: number;
@@ -17,6 +17,8 @@ interface BranchesItemProps {
   paramsOptions: any[];
   onDelete: () => void;
   onDeleteAll?: () => void;
+  form: FormInstance;
+  className?: string;
 }
 
 export default observer((props: BranchesItemProps) => {
@@ -64,7 +66,7 @@ export default observer((props: BranchesItemProps) => {
   };
 
   return (
-    <div className="actions-terms-warp">
+    <div className={classNames('actions-terms-warp', props.className)}>
       <div className="actions-terms-title">{props.isFirst ? '当' : '否则'}</div>
       <div
         className={classNames('actions-terms-options', { border: !props.isFirst, error: error })}
@@ -140,27 +142,43 @@ export default observer((props: BranchesItemProps) => {
           <Observer>
             {() => {
               return (
-                <Actions
-                  openShakeLimit={true}
-                  name={props.name}
-                  thenOptions={props.data.then}
-                  onAdd={(data) => {
-                    if (FormModel.current.branches && data) {
-                      FormModel.current.branches[props.name].then = [
-                        ...FormModel.current.branches[props.name].then,
-                        data,
-                      ];
-                    }
-                  }}
-                  onUpdate={(data, type) => {
-                    const indexOf = FormModel.current.branches![props.name].then.findIndex(
-                      (item) => item.parallel === type,
-                    );
-                    if (indexOf !== -1) {
-                      FormModel.current.branches![props.name].then[indexOf] = data;
-                    }
-                  }}
-                />
+                <Form.Item
+                  name={['branches', props.name, 'then']}
+                  rules={[
+                    {
+                      validator(_, v) {
+                        if (!v || (v && !v.length)) {
+                          return Promise.reject('至少配置一个执行动作');
+                        }
+                        return Promise.resolve();
+                      },
+                    },
+                  ]}
+                >
+                  <Actions
+                    openShakeLimit={true}
+                    name={props.name}
+                    thenOptions={props.data.then}
+                    onAdd={(data) => {
+                      if (FormModel.current.branches && data) {
+                        const newThen = [...FormModel.current.branches[props.name].then, data];
+                        FormModel.current.branches[props.name].then = newThen;
+                      }
+                    }}
+                    onUpdate={(data, type) => {
+                      const indexOf = FormModel.current.branches![props.name].then.findIndex(
+                        (item) => item.parallel === type,
+                      );
+                      if (indexOf !== -1) {
+                        if (data.actions?.length) {
+                          FormModel.current.branches![props.name].then[indexOf] = data;
+                        } else {
+                          FormModel.current.branches![props.name].then = [];
+                        }
+                      }
+                    }}
+                  />
+                </Form.Item>
               );
             }}
           </Observer>

+ 14 - 3
src/pages/rule-engine/Scene/Save/terms/index.less

@@ -30,9 +30,11 @@
 .actions-terms {
   .actions-terms-warp {
     display: flex;
+    margin-bottom: 24px;
 
-    &:not(:last-child) {
-      margin-bottom: 24px;
+    &.first-children,
+    &:last-child {
+      margin-bottom: 0;
     }
 
     .actions-terms-title {
@@ -51,7 +53,7 @@
       width: 0;
 
       &.border {
-        padding: 10px 18px 18px 18px;
+        padding: 10px 18px 0 18px;
         border: 1px dashed #999;
         border-radius: 2px;
       }
@@ -62,6 +64,13 @@
 
       .actions-terms-list {
         position: relative;
+        margin-bottom: 16px;
+
+        .ant-form-item-has-error {
+          .params-item_button {
+            border-color: @error-color;
+          }
+        }
 
         .actions-terms-list-content {
           display: flex;
@@ -103,6 +112,7 @@
     display: flex;
     // flex-wrap: wrap;
     padding: 8px;
+    padding-bottom: 0;
     background-color: #fafafa;
     row-gap: 16px;
     .terms-params-item {
@@ -156,6 +166,7 @@
     padding: 4px;
     border: 1px solid rgba(0, 0, 0, 0.1);
     border-radius: 2px;
+    transition: border 0.3s;
 
     // > div {
     //   flex-shrink: 0;

+ 71 - 36
src/pages/rule-engine/Scene/Save/terms/index.tsx

@@ -1,11 +1,11 @@
-import { useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
 import { TitleComponent } from '@/components';
 import { observer, Observer } from '@formily/react';
 import { model } from '@formily/reactive';
 import { FormModel, defaultBranches } from '@/pages/rule-engine/Scene/Save';
 import BranchItem from './branchItem';
 import { service } from '@/pages/rule-engine/Scene/index';
-import { Form, Switch } from 'antd';
+import { Form, FormInstance, Switch } from 'antd';
 import type { TriggerType } from '@/pages/rule-engine/Scene/typings';
 import Actions from '@/pages/rule-engine/Scene/Save/action';
 import { cloneDeep, set } from 'lodash';
@@ -21,7 +21,11 @@ export const TermsModel = model<TermsModelProps>({
   columnOptions: [],
 });
 
-export default observer(() => {
+interface Props {
+  form: FormInstance;
+}
+
+export default observer((props: Props) => {
   const [open, setOpen] = useState(true);
 
   useEffect(() => {
@@ -46,37 +50,43 @@ export default observer(() => {
     });
   };
 
-  const openChange = (checked: boolean) => {
-    setOpen(checked);
-    const key = randomString();
-    if (checked) {
-      FormModel.current.branches = cloneDeep([...defaultBranches, null as any]);
-      set(FormModel.current.options!, 'when', [
-        {
-          terms: [
-            {
-              terms: [],
+  const openChange = useCallback(
+    (checked: boolean) => {
+      setOpen(checked);
+      const key = randomString();
+      if (checked) {
+        FormModel.current.branches = cloneDeep([...defaultBranches, null as any]);
+        set(FormModel.current.options!, 'when', [
+          {
+            terms: [
+              {
+                terms: [],
+              },
+            ],
+          },
+        ]);
+        props.form.setFieldValue(['branches'], [...defaultBranches]);
+      } else {
+        const newValue = [
+          {
+            when: [],
+            key: 'branches_' + key,
+            shakeLimit: {
+              enabled: false,
+              time: 0,
+              threshold: 0,
+              alarmFirst: false,
             },
-          ],
-        },
-      ]);
-    } else {
-      FormModel.current.branches = [
-        {
-          when: [],
-          key: 'branches_' + key,
-          shakeLimit: {
-            enabled: false,
-            time: 0,
-            threshold: 0,
-            alarmFirst: false,
+            then: [],
           },
-          then: [],
-        },
-      ];
-      set(FormModel.current.options!, 'when', []);
-    }
-  };
+        ];
+        FormModel.current.branches = newValue;
+        set(FormModel.current.options!, 'when', []);
+        props.form.setFieldValue(['branches'], newValue);
+      }
+    },
+    [props.form],
+  );
 
   const addBranches = () => {
     const key = randomString();
@@ -123,8 +133,10 @@ export default observer(() => {
               const isFirst = index === 0;
               return item ? (
                 <BranchItem
+                  form={props.form}
                   data={item}
                   isFirst={isFirst}
+                  className={isFirst ? 'first-children' : ''}
                   name={index}
                   key={item.key}
                   paramsOptions={TermsModel.columnOptions}
@@ -145,7 +157,13 @@ export default observer(() => {
                   }}
                 />
               ) : (
-                <div className="actions-terms-warp" style={{ alignItems: 'center' }}>
+                <div
+                  className="actions-terms-warp"
+                  style={{
+                    alignItems: 'center',
+                    marginTop: FormModel.current.branches?.length === 2 ? 0 : 24,
+                  }}
+                >
                   <div className="actions-terms-title" style={{ padding: 0 }}>
                     否则
                   </div>
@@ -162,14 +180,27 @@ export default observer(() => {
           }
         </Observer>
       ) : (
-        <Form.Item>
+        <Form.Item
+          name={['branches', 0, 'then']}
+          rules={[
+            {
+              validator(_, v) {
+                if (!v || (v && !v.length)) {
+                  return Promise.reject('至少配置一个执行动作');
+                }
+                return Promise.resolve();
+              },
+            },
+          ]}
+        >
           <Actions
             openShakeLimit={true}
             name={0}
             thenOptions={FormModel.current.branches ? FormModel.current.branches[0].then : []}
             onAdd={(data) => {
               if (FormModel.current.branches && data) {
-                FormModel.current.branches[0].then = [...FormModel.current.branches[0].then, data];
+                const newThen = [...FormModel.current.branches[0].then, data];
+                FormModel.current.branches[0].then = newThen;
               }
             }}
             onUpdate={(data, type) => {
@@ -177,7 +208,11 @@ export default observer(() => {
                 (item) => item.parallel === type,
               );
               if (indexOf !== -1) {
-                FormModel.current.branches![0].then[indexOf] = data;
+                if (data.actions?.length) {
+                  FormModel.current.branches![0].then[indexOf] = data;
+                } else {
+                  FormModel.current.branches![0].then = [];
+                }
               }
             }}
           />

+ 15 - 5
src/pages/rule-engine/Scene/Save/terms/paramsItem.tsx

@@ -20,6 +20,7 @@ interface ParamsItemProps {
   isDelete: boolean;
   options: any[];
   onValueChange?: (value: TermsType) => void;
+  onChange?: (value: TermsType) => void;
   onLabelChange?: (label: string[]) => void;
   label?: any[];
   onAdd: () => void;
@@ -108,6 +109,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
   const [termType, setTermType] = useState('');
   const [column, setColumn] = useState('');
   const labelCache = useRef<any[]>([undefined, undefined, {}, 'and']);
+  const firstLockRef = useRef(true);
 
   const ValueRef = useRef<Partial<TermsType>>({
     column: '',
@@ -164,6 +166,11 @@ const ParamsItem = observer((props: ParamsItemProps) => {
     setColumn(props.data.column || '');
     ValueRef.current = props.data || {};
     convertLabelValue(props.data.column);
+    if (!firstLockRef.current) {
+      props.onChange?.(props.data);
+    } else {
+      firstLockRef.current = false;
+    }
   }, [props.data]);
 
   useEffect(() => {
@@ -171,7 +178,6 @@ const ParamsItem = observer((props: ParamsItemProps) => {
   }, [props.options]);
 
   useEffect(() => {
-    console.log('params-effect', props.label);
     labelCache.current = props.label || [undefined, undefined, {}, 'and'];
   }, [props.label]);
 
@@ -273,7 +279,8 @@ const ParamsItem = observer((props: ParamsItemProps) => {
                 ValueRef.current.value = _myValue;
                 setValue(_myValue);
                 labelCache.current[2] = { ...labelCache.current[2], 0: lb };
-                props.onLabelChange?.([...labelCache.current, props.data.type]);
+                labelCache.current[3] = props.data.type;
+                props.onLabelChange?.([...labelCache.current]);
                 valueEventChange(_myValue);
               }}
             />
@@ -293,7 +300,8 @@ const ParamsItem = observer((props: ParamsItemProps) => {
                 ValueRef.current.value = _myValue;
                 setValue(_myValue);
                 labelCache.current[2] = { ...labelCache.current[2], 1: lb };
-                props.onLabelChange?.([...labelCache.current, props.data.type]);
+                labelCache.current[3] = props.data.type;
+                props.onLabelChange?.([...labelCache.current]);
                 valueEventChange(_myValue);
               }}
             />
@@ -313,7 +321,8 @@ const ParamsItem = observer((props: ParamsItemProps) => {
               ValueRef.current.value = v;
               labelCache.current[2] = { 0: lb };
               console.log('valueChange', labelCache.current);
-              props.onLabelChange?.([...labelCache.current, props.data.type]);
+              labelCache.current[3] = props.data.type;
+              props.onLabelChange?.([...labelCache.current]);
               valueEventChange(v);
             }}
           />
@@ -336,7 +345,8 @@ const ParamsItem = observer((props: ParamsItemProps) => {
             value={props.data.type}
             onChange={(v) => {
               props.data.type = v;
-              props.onLabelChange?.([...labelCache.current, v]);
+              labelCache.current[3] = v;
+              props.onLabelChange?.([...labelCache.current]);
             }}
           />
         </div>

+ 87 - 55
src/pages/rule-engine/Scene/Save/terms/term.tsx

@@ -6,9 +6,9 @@ import { CloseOutlined, PlusOutlined } from '@ant-design/icons';
 import { DropdownButton } from '@/pages/rule-engine/Scene/Save/components/Buttons';
 import classNames from 'classnames';
 import type { TermsType } from '@/pages/rule-engine/Scene/typings';
-import { get, set } from 'lodash';
+import { get, isArray, set } from 'lodash';
 import './index.less';
-import { Popconfirm } from 'antd';
+import { Form, Popconfirm } from 'antd';
 
 interface TermsProps {
   data: TermsType;
@@ -66,61 +66,93 @@ export default observer((props: TermsProps) => {
               const _when = get(FormModel.current.branches, [...props.pName, props.name]);
               const terms: TermsType[] = _when?.terms || [];
               return terms.map((item, index) => (
-                <ParamsItem
-                  pName={[...props.pName, props.name]}
-                  isDelete={terms.length > 1}
-                  name={index}
-                  data={item}
-                  key={item.key}
-                  isLast={index === props.data.terms!.length - 1}
-                  options={props.paramsOptions}
-                  label={
-                    FormModel.current.options?.when?.[props.whenName]?.terms?.[props.name]?.terms?.[
-                      index
-                    ]
-                  }
-                  onDelete={() => {
-                    terms.splice(index, 1);
-                    // setTerms([...terms]);
-                    // props.onValueChange({
-                    //   terms: terms,
-                    // });
-                  }}
-                  onAdd={() => {
-                    const key = `params_${new Date().getTime()}`;
-                    terms.push({
-                      type: 'and',
-                      column: undefined,
-                      value: undefined,
-                      termType: undefined,
-                      key,
-                    });
+                <Form.Item
+                  name={['branches', ...props.pName, props.name, 'terms', index]}
+                  rules={[
+                    {
+                      validator(_, v) {
+                        if (v) {
+                          if (!v.column) {
+                            return Promise.reject(new Error('请选择参数'));
+                          }
 
-                    // setTerms([...terms]);
-                    props.onValueChange({
-                      ..._when,
-                      terms: terms,
-                    });
-                  }}
-                  onValueChange={(data) => {
-                    terms[index] = {
-                      ...terms[index],
-                      ...data,
-                    };
+                          if (!v.termType) {
+                            return Promise.reject(new Error('请选择操作符'));
+                          }
 
-                    // setTerms([...terms]);
-                    props.onValueChange({
-                      ..._when,
-                      terms: terms,
-                    });
-                  }}
-                  onLabelChange={(options) => {
-                    FormModel.current.options!.when[props.whenName].terms[props.name].terms[index] =
-                      options;
-                    FormModel.current.options!.when[props.whenName].terms[props.name].termType =
-                      props.data.type === 'and' ? '并且' : '或者';
-                  }}
-                />
+                          if (!v.value) {
+                            return Promise.reject(new Error('请选择或输入参数值'));
+                          } else {
+                            if (isArray(v.value.value) && v.value.value.some((_v: any) => !_v)) {
+                              return Promise.reject(new Error('请选择或输入参数值'));
+                            } else if (!v.value.value) {
+                              return Promise.reject(new Error('请选择或输入参数值'));
+                            }
+                          }
+                        } else {
+                          return Promise.reject(new Error('请选择参数'));
+                        }
+                        return Promise.resolve();
+                      },
+                    },
+                  ]}
+                >
+                  <ParamsItem
+                    pName={[...props.pName, props.name]}
+                    isDelete={terms.length > 1}
+                    name={index}
+                    data={item}
+                    key={item.key}
+                    isLast={index === props.data.terms!.length - 1}
+                    options={props.paramsOptions}
+                    label={
+                      FormModel.current.options?.when?.[props.whenName]?.terms?.[props.name]
+                        ?.terms?.[index]
+                    }
+                    onDelete={() => {
+                      terms.splice(index, 1);
+                      // setTerms([...terms]);
+                      // props.onValueChange({
+                      //   terms: terms,
+                      // });
+                    }}
+                    onAdd={() => {
+                      const key = `params_${new Date().getTime()}`;
+                      terms.push({
+                        type: 'and',
+                        column: undefined,
+                        value: undefined,
+                        termType: undefined,
+                        key,
+                      });
+
+                      // setTerms([...terms]);
+                      props.onValueChange({
+                        ..._when,
+                        terms: terms,
+                      });
+                    }}
+                    onValueChange={(data) => {
+                      terms[index] = {
+                        ...terms[index],
+                        ...data,
+                      };
+
+                      // setTerms([...terms]);
+                      props.onValueChange({
+                        ..._when,
+                        terms: terms,
+                      });
+                    }}
+                    onLabelChange={(options) => {
+                      FormModel.current.options!.when[props.whenName].terms[props.name].terms[
+                        index
+                      ] = options;
+                      FormModel.current.options!.when[props.whenName].terms[props.name].termType =
+                        props.data.type === 'and' ? '并且' : '或者';
+                    }}
+                  />
+                </Form.Item>
               ));
             }}
           </Observer>

+ 1 - 7
src/pages/rule-engine/Scene/Save/timer/index.tsx

@@ -80,7 +80,7 @@ export default observer((props: Props) => {
               rules={[
                 {
                   validator(_, v) {
-                    if (v && !v.length) {
+                    if (!v || (v && !v.length)) {
                       return Promise.reject('至少配置一个执行动作');
                     }
                     return Promise.resolve();
@@ -95,8 +95,6 @@ export default observer((props: Props) => {
                   if (FormModel.current.branches && data) {
                     const newThen = [...FormModel.current.branches[0].then, data];
                     FormModel.current.branches[0].then = newThen;
-                    props.form.setFieldValue(['branches', 0, 'then'], newThen);
-                    props.form.validateFields(['branches', 0, 'then']);
                   }
                 }}
                 onUpdate={(data, type) => {
@@ -109,10 +107,6 @@ export default observer((props: Props) => {
                     } else {
                       FormModel.current.branches![0].then = [];
                     }
-                    props.form.setFieldValue(
-                      ['branches', 0, 'then'],
-                      FormModel.current.branches![0].then,
-                    );
                   }
                 }}
               />