Parcourir la source

fix: merge next

wzyyy il y a 3 ans
Parent
commit
c423cf3f7d

+ 3 - 2
src/components/ProTableCard/CardItems/Scene/index.tsx

@@ -133,7 +133,7 @@ const notifyRender = (data: ActionsType | undefined) => {
     case 'dingTalk':
       if (data?.options?.provider === 'dingTalkRobotWebHook') {
         return (
-          <div>
+          <div className={styles['notify-img-highlight']}>
             通过<span className={'notify-text-highlight'}>群机器人消息</span>
             发送<span>{data?.options?.templateName || data?.notify?.templateId}</span>
           </div>
@@ -167,7 +167,7 @@ const notifyRender = (data: ActionsType | undefined) => {
     case 'voice':
       return (
         <div className={styles['notify-img-highlight']}>
-          向<span>{data?.options?.calledNumber || ''}</span>
+          向<span>{data?.options?.sendTo || ''}</span>
           通过<span>语音</span>发送
           <span>{data?.options?.templateName || data?.notify?.templateId}</span>
         </div>
@@ -341,6 +341,7 @@ const branchesActionRender = (actions: any[]) => {
 const ContentRender = (data: SceneCardProps) => {
   const [visible, setVisible] = useState<boolean>(false);
   const type = data.triggerType;
+
   if (!!type && (data.branches || [])?.length) {
     const trigger = data?.options?.trigger;
     return (

+ 6 - 7
src/pages/rule-engine/Scene/Save/action/ListItem/FilterCondition.tsx

@@ -7,7 +7,7 @@ import { observer } from '@formily/react';
 import { queryBuiltInParams } from '@/pages/rule-engine/Scene/Save/action/service';
 import '../index.less';
 import { FormModel } from '../..';
-import { Space } from 'antd';
+import { Popconfirm, Space } from 'antd';
 import { cloneDeep } from 'lodash';
 
 interface FilterProps {
@@ -166,12 +166,11 @@ export default observer((props: FilterProps) => {
     <div className="filter-condition-warp">
       {props.data ? (
         <div className="filter-condition-content">
-          <div
-            className={classNames('filter-condition-delete danger show')}
-            onClick={props.onDelete}
-          >
-            <DeleteOutlined />
-          </div>
+          <Popconfirm title={'确认删除?'} onConfirm={props.onDelete}>
+            <div className={classNames('filter-condition-delete danger show')}>
+              <DeleteOutlined />
+            </div>
+          </Popconfirm>
           <DropdownButton
             options={columnOptions}
             type="param"

+ 37 - 31
src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx

@@ -7,6 +7,7 @@ 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';
 
 export enum ParallelEnum {
   'parallel' = 'parallel',
@@ -14,6 +15,7 @@ export enum ParallelEnum {
 }
 
 export type ParallelType = keyof typeof ParallelEnum;
+
 interface ItemProps {
   thenName: number;
   branchGroup?: number;
@@ -116,7 +118,7 @@ export default (props: ItemProps) => {
       case 'voice':
         return (
           <div>
-            向<span className={'notify-text-highlight'}>{options?.calledNumber || ''}</span>
+            向<span className={'notify-text-highlight'}>{options?.sendTo || ''}</span>
             通过
             <span className={'notify-img-highlight'}>
               <img width={18} src={itemNotifyIconMap.get(data?.notify?.notifyType)} />
@@ -199,33 +201,35 @@ export default (props: ItemProps) => {
   };
 
   const contentRender = () => {
-    if (props?.data?.alarm?.mode === 'trigger') {
-      return (
-        <div className={'item-options-content'}>
-          满足条件后将触发
-          <a
-            onClick={(e) => {
-              e.stopPropagation();
-              setTriggerVisible(true);
-            }}
-          >
-            关联此场景的告警
-          </a>
-        </div>
-      );
-    } else if (props?.data?.alarm?.mode === 'relieve') {
-      return (
-        <div className={'item-options-content'}>
-          满足条件后将解除
-          <a
-            onClick={() => {
-              setTriggerVisible(true);
-            }}
-          >
-            关联此场景的告警
-          </a>
-        </div>
-      );
+    if (props?.data?.executor === 'alarm') {
+      if (props?.data?.alarm?.mode === 'trigger') {
+        return (
+          <div className={'item-options-content'}>
+            满足条件后将触发
+            <a
+              onClick={(e) => {
+                e.stopPropagation();
+                setTriggerVisible(true);
+              }}
+            >
+              关联此场景的告警
+            </a>
+          </div>
+        );
+      } else if (props?.data?.alarm?.mode === 'relieve') {
+        return (
+          <div className={'item-options-content'}>
+            满足条件后将解除
+            <a
+              onClick={() => {
+                setTriggerVisible(true);
+              }}
+            >
+              关联此场景的告警
+            </a>
+          </div>
+        );
+      }
     } else if (props?.data?.executor === 'notify') {
       return (
         <div
@@ -295,9 +299,11 @@ export default (props: ItemProps) => {
           {contentRender()}
         </div>
         <div className="item-number">{props.name + 1}</div>
-        <div className="item-delete" onClick={props.onDelete}>
-          <DeleteOutlined />
-        </div>
+        <Popconfirm title={'确认删除?'} onConfirm={props.onDelete}>
+          <div className="item-delete">
+            <DeleteOutlined />
+          </div>
+        </Popconfirm>
       </div>
       {props.parallel ? null : (
         <FilterCondition

+ 0 - 15
src/pages/rule-engine/Scene/Save/action/ListItem/List.tsx

@@ -20,7 +20,6 @@ export default (props: ListProps) => {
 
   useEffect(() => {
     setActions(props.actions);
-    // console.log('list-change', props.actions);
   }, [props.actions]);
 
   return (
@@ -69,26 +68,12 @@ export default (props: ListProps) => {
             setVisible(false);
           }}
           save={(data: any, options) => {
-            console.log(data);
-
             const { type, ...extra } = data;
-            console.log('list', options);
             const item: ActionsType = {
               ...extra,
-              executor: data.type === 'trigger' || data.type === 'relieve' ? 'alarm' : data.type,
               key: data.key,
               options,
             };
-
-            if (data.type === 'trigger' || data.type === 'relieve') {
-              item.alarm = {
-                mode: data.type,
-              };
-            }
-            // const index = FormModel?.actions.findIndex((i) => {
-            //   return i.key === item.key ? item : i;
-            // });
-            // FormModel.actions[index] = { ...item };
             props.onAdd(item);
             setVisible(false);
           }}

+ 2 - 2
src/pages/rule-engine/Scene/Save/action/Modal/add.tsx

@@ -129,7 +129,7 @@ export default (props: Props) => {
         const values = await form.validateFields();
         setActionType(values.type);
         if (values.type === 'relieve' || values.type === 'trigger') {
-          props.save({ ...props.data, type: values.type, executor: 'alarm' });
+          props.save({ ...props.data, executor: 'alarm', alarm: { mode: values.type } }, {});
         }
       }}
     >
@@ -147,7 +147,7 @@ export default (props: Props) => {
         {...props}
         type={actionType}
         save={(data: any, options?: any) => {
-          props.save(data, options);
+          props.save({ ...data, executor: data.type }, options);
           setActionType('');
         }}
         close={() => {

+ 1 - 1
src/pages/rule-engine/Scene/Save/action/index.less

@@ -24,7 +24,7 @@
     display: flex;
     gap: 16px;
     align-items: center;
-    margin: 16px 0;
+    margin-bottom: 16px;
     font-weight: 800;
     font-size: 14px;
     line-height: 32px;

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

@@ -17,15 +17,24 @@ interface ActionsProps {
   thenOptions: BranchesThen[];
   onAdd: (data: BranchesThen) => void;
   onUpdate: (data: BranchesThen, type: boolean) => 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);
 
   useEffect(() => {
-    setParallelArray(props.thenOptions.filter((item) => item.parallel));
-    setSerialArray(props.thenOptions.filter((item) => !item.parallel));
+    const parallelArr = props.thenOptions.filter((item) => item.parallel);
+    const serialArr = props.thenOptions.filter((item) => !item.parallel);
+    setParallelArray(parallelArr);
+    setSerialArray(serialArr);
+    if (!lock && parallelArr.length && !serialArr.length) {
+      setActiveKey(['2']);
+      setLock(true);
+    }
   }, [props.thenOptions]);
 
   return (
@@ -55,7 +64,7 @@ export default (props: ActionsProps) => {
         ) : null}
       </div>
       <div className="actions-warp">
-        <Collapse defaultActiveKey={['1']}>
+        <Collapse activeKey={activeKeys} onChange={setActiveKey}>
           <Panel
             header={
               <span>

+ 2 - 0
src/pages/rule-engine/Scene/Save/action/notify/NotifyConfig.tsx

@@ -71,6 +71,8 @@ export default observer((props: Props) => {
             onChange: (selectedRowKeys, list) => {
               if (selectedRowKeys.length) {
                 NotifyModel.notify.notifierId = String(selectedRowKeys[selectedRowKeys.length - 1]);
+                NotifyModel.notify.templateId = '';
+                NotifyModel.variable = [];
                 NotifyModel.notify.options = {
                   ...NotifyModel.notify.options,
                   provider: list[list.length - 1]?.provider,

+ 1 - 0
src/pages/rule-engine/Scene/Save/action/notify/NotifyTemplate.tsx

@@ -71,6 +71,7 @@ export default observer((props: Props) => {
             onChange: (selectedRowKeys, list) => {
               if (selectedRowKeys.length) {
                 NotifyModel.notify.templateId = String(selectedRowKeys[selectedRowKeys.length - 1]);
+                NotifyModel.variable = [];
                 NotifyModel.notify.options = {
                   ...NotifyModel.notify.options,
                   templateName: list[list.length - 1]?.name,

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

@@ -24,6 +24,7 @@ export const NotifyModel = model<{
   current: number;
   notify: Partial<NotifyProps>;
   variable: any[];
+  loading: boolean;
 }>({
   steps: [
     {
@@ -50,6 +51,7 @@ export const NotifyModel = model<{
     templateId: '',
   },
   variable: [],
+  loading: false,
 });
 
 export default observer((props: Props) => {
@@ -89,10 +91,16 @@ export default observer((props: Props) => {
   };
 
   const next = async () => {
+    NotifyModel.loading = true;
     if (NotifyModel.current === 0) {
       const val = await WayRef.current?.save();
       if (val) {
-        NotifyModel.notify.notifyType = val;
+        NotifyModel.notify = {
+          notifyType: val,
+          notifierId: '',
+          templateId: '',
+        };
+        NotifyModel.variable = [];
         NotifyModel.current += 1;
       }
     } else if (NotifyModel.current === 1) {
@@ -126,6 +134,7 @@ export default observer((props: Props) => {
         NotifyModel.current = 0;
       }
     }
+    NotifyModel.loading = false;
   };
 
   return (
@@ -157,6 +166,7 @@ export default observer((props: Props) => {
           {NotifyModel.current < NotifyModel.steps.length - 1 && (
             <Button
               type="primary"
+              loading={NotifyModel.loading}
               onClick={() => {
                 next();
               }}
@@ -178,7 +188,38 @@ export default observer((props: Props) => {
       }
     >
       <div className="steps-steps">
-        <Steps current={NotifyModel.current} items={NotifyModel.steps} />
+        <Steps
+          onChange={async (value: number) => {
+            if (value === 0) {
+              NotifyModel.current = value;
+            }
+            if (value === 1) {
+              if (NotifyModel.notify.notifyType) {
+                NotifyModel.current = value;
+              } else {
+                onlyMessage('请选择通知方式', 'error');
+              }
+            } else if (value === 2) {
+              if (NotifyModel.notify.notifierId) {
+                NotifyModel.current = value;
+              } else {
+                onlyMessage('请选择通知配置', 'error');
+              }
+            } else if (value === 3) {
+              if (NotifyModel.notify.templateId) {
+                const resp = await queryMessageTemplateDetail(NotifyModel.notify.templateId);
+                if (resp.status === 200) {
+                  NotifyModel.variable = resp.result?.variableDefinitions || [];
+                  NotifyModel.current = value;
+                }
+              } else {
+                onlyMessage('请选择通知模板', 'error');
+              }
+            }
+          }}
+          current={NotifyModel.current}
+          items={NotifyModel.steps}
+        />
       </div>
       <div className="steps-content">
         {renderComponent(NotifyModel.steps[NotifyModel.current]?.key)}

+ 37 - 15
src/pages/rule-engine/Scene/Save/device/index.tsx

@@ -12,6 +12,8 @@ import { Store } from 'jetlinks-store';
 import { TriggerDeviceModel } from './addModel';
 import { handleMetadata } from './product';
 import { set } from 'lodash';
+import { Form, FormInstance } from 'antd';
+import { TitleComponent } from '@/components';
 
 const defaultDeviceValue = {
   productId: '',
@@ -19,7 +21,11 @@ const defaultDeviceValue = {
   selectorValues: [],
 };
 
-export default observer(() => {
+interface Props {
+  form: FormInstance;
+}
+
+export default observer((props: Props) => {
   const [visible, setVisible] = useState(false);
 
   useEffect(() => {
@@ -38,7 +44,6 @@ export default observer(() => {
   }, [FormModel.current.trigger!.device?.productId]);
 
   const handleLabel = (options: any): ReactChild | ReactChild[] => {
-    console.log('FormModel', options);
     if (!options || !Object.keys(options).length) return '点击配置设备触发';
 
     const _label = [<span className="trigger-options-name">{options.name}</span>];
@@ -66,26 +71,41 @@ export default observer(() => {
   };
 
   return (
-    <div>
+    <div style={{ marginBottom: 24 }}>
       <div style={{ marginBottom: 16 }}>
         <Observer>
           {() => {
             const label = handleLabel(FormModel.current.options?.trigger);
             return (
-              <AddButton
-                style={{ width: '100%' }}
-                onClick={() => {
-                  setVisible(true);
-                }}
+              <Form.Item
+                label={<TitleComponent style={{ fontSize: 14 }} data={'设备触发'} />}
+                name={'device'}
+                rules={[
+                  {
+                    validator(_, v) {
+                      if (!v) {
+                        return Promise.reject(new Error('请配置设备触发规则'));
+                      }
+                      return Promise.resolve();
+                    },
+                  },
+                ]}
               >
-                <div
-                  className={classNames('trigger-options-content', {
-                    'is-add': !!Object.keys(FormModel.current.options?.trigger || {}).length,
-                  })}
+                <AddButton
+                  style={{ width: '100%' }}
+                  onClick={() => {
+                    setVisible(true);
+                  }}
                 >
-                  {label}
-                </div>
-              </AddButton>
+                  <div
+                    className={classNames('trigger-options-content', {
+                      'is-add': !!Object.keys(FormModel.current.options?.trigger || {}).length,
+                    })}
+                  >
+                    {label}
+                  </div>
+                </AddButton>
+              </Form.Item>
             );
           }}
         </Observer>
@@ -100,6 +120,8 @@ export default observer(() => {
             console.log('FormModel.current.options', data);
             set(FormModel.current, ['options', 'trigger'], options);
             set(FormModel.current, ['trigger', 'device'], data);
+            props.form.setFieldValue('device', data);
+            props.form.validateFields(['device']);
           }}
           onCancel={() => {
             setVisible(false);

+ 16 - 17
src/pages/rule-engine/Scene/Save/index.tsx

@@ -1,5 +1,5 @@
 import { PageContainer } from '@ant-design/pro-layout';
-import { Button, Card, Form, Input } from 'antd';
+import { Button, Card, Form, FormInstance, Input } from 'antd';
 import useLocation from '@/hooks/route/useLocation';
 import Device from '../Save/device/index';
 import Manual from '../Save/manual/index';
@@ -141,39 +141,38 @@ 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);
+          }
+          form.setFieldValue('branches', newBranches);
         }
       });
     }
   }, [id, form]);
 
-  const triggerRender = (type: string) => {
+  const triggerRender = (type: string, _form: FormInstance) => {
     FormModel.current.trigger!.type = type;
     switch (type) {
       case 'device':
-        return (
-          <Form.Item label={<TitleComponent style={{ fontSize: 14 }} data={'设备触发'} />}>
-            <Device />
-          </Form.Item>
-        );
+        return <Device form={_form} />;
       case 'manual':
         return (
           <Form.Item label={<TitleComponent style={{ fontSize: 14 }} data={'手动触发'} />}>
-            <Manual />
+            <Manual form={_form} />
           </Form.Item>
         );
       case 'timer':
-        return (
-          <Form.Item label={<TitleComponent style={{ fontSize: 14 }} data={'定时触发'} />}>
-            <Timer />
-          </Form.Item>
-        );
+        return <Timer form={_form} />;
       default:
         return null;
     }
   };
 
-  const submit = useCallback(() => {
-    const baseData = form.getFieldsValue();
+  const submit = useCallback(async () => {
+    const baseData = await form.validateFields();
+    console.log('submit', baseData);
+    if (!baseData) return;
+
     const FormData = cloneDeep(FormModel.current);
     const { options, branches } = FormData;
     if (options?.terms) {
@@ -206,8 +205,8 @@ export default observer(() => {
   return (
     <PageContainer>
       <Card>
-        <Form name="timer" layout={'vertical'} form={form}>
-          {triggerRender(triggerType)}
+        <Form layout={'vertical'} form={form}>
+          {triggerRender(triggerType, form)}
           <Form.Item
             label={<TitleComponent style={{ fontSize: 14 }} data={'说明'} />}
             name="description"

+ 47 - 18
src/pages/rule-engine/Scene/Save/manual/index.tsx

@@ -1,29 +1,58 @@
 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;
+}
 
-export default () => {
+export default (props: Props) => {
   return (
     <div>
       <Observer>
         {() => (
-          <Action
-            thenOptions={FormModel.current.branches ? FormModel.current.branches[0].then : []}
-            name={0}
-            onAdd={(data) => {
-              if (FormModel.current.branches && data) {
-                FormModel.current.branches[0].then = [...FormModel.current.branches[0].then, data];
-              }
-            }}
-            onUpdate={(data, type) => {
-              const indexOf = FormModel.current.branches![0].then.findIndex(
-                (item) => item.parallel === type,
-              );
-              if (indexOf !== -1) {
-                FormModel.current.branches![0].then[indexOf] = data;
-              }
-            }}
-          />
+          <Form.Item
+            name={['branches', 0, 'then']}
+            rules={[
+              {
+                validator(_, v) {
+                  if (v && !v.length) {
+                    return Promise.reject('至少配置一个执行动作');
+                  }
+                  return Promise.resolve();
+                },
+              },
+            ]}
+          >
+            <Action
+              thenOptions={FormModel.current.branches ? FormModel.current.branches[0].then : []}
+              name={0}
+              onAdd={(data) => {
+                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) => {
+                const indexOf = FormModel.current.branches![0].then.findIndex(
+                  (item) => item.parallel === type,
+                );
+                if (indexOf !== -1) {
+                  if (data.actions?.length) {
+                    FormModel.current.branches![0].then[indexOf] = data;
+                  } else {
+                    FormModel.current.branches![0].then = [];
+                  }
+                  props.form.setFieldValue(
+                    ['branches', 0, 'then'],
+                    FormModel.current.branches![0].then,
+                  );
+                }
+              }}
+            />
+          </Form.Item>
         )}
       </Observer>
     </div>

+ 9 - 8
src/pages/rule-engine/Scene/Save/terms/branchItem.tsx

@@ -9,6 +9,7 @@ import classNames from 'classnames';
 import { set } from 'lodash';
 import { Store } from 'jetlinks-store';
 import { Popconfirm } from 'antd';
+
 interface BranchesItemProps {
   name: number;
   data: ActionBranchesProps;
@@ -84,15 +85,15 @@ export default observer((props: BranchesItemProps) => {
             if (!props.isFirst && when.length) setDeleteVisible(false);
           }}
         >
-          <div className={classNames('terms-params-delete', { show: deleteVisible })}>
-            <Popconfirm
-              title={'该操作将清空其它所有否则条件,确认删除?'}
-              placement="topRight"
-              onConfirm={props.onDeleteAll}
-            >
+          <Popconfirm
+            title={'该操作将清空其它所有否则条件,确认删除?'}
+            placement="topRight"
+            onConfirm={props.onDeleteAll}
+          >
+            <div className={classNames('terms-params-delete', { show: deleteVisible })}>
               <CloseOutlined />
-            </Popconfirm>
-          </div>
+            </div>
+          </Popconfirm>
           <div className="actions-terms-list-content">
             <Observer>
               {() =>

+ 21 - 19
src/pages/rule-engine/Scene/Save/terms/index.tsx

@@ -5,7 +5,7 @@ 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 { Switch } from 'antd';
+import { Form, 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';
@@ -162,24 +162,26 @@ export default observer(() => {
           }
         </Observer>
       ) : (
-        <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];
-            }
-          }}
-          onUpdate={(data, type) => {
-            const indexOf = FormModel.current.branches![0].then.findIndex(
-              (item) => item.parallel === type,
-            );
-            if (indexOf !== -1) {
-              FormModel.current.branches![0].then[indexOf] = data;
-            }
-          }}
-        />
+        <Form.Item>
+          <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];
+              }
+            }}
+            onUpdate={(data, type) => {
+              const indexOf = FormModel.current.branches![0].then.findIndex(
+                (item) => item.parallel === type,
+              );
+              if (indexOf !== -1) {
+                FormModel.current.branches![0].then[indexOf] = data;
+              }
+            }}
+          />
+        </Form.Item>
       )}
     </div>
   );

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

@@ -318,11 +318,11 @@ const ParamsItem = observer((props: ParamsItemProps) => {
             }}
           />
         )}
-        <div className={classNames('button-delete', { show: deleteVisible })}>
-          <Popconfirm title={'确认删除?'} onConfirm={props.onDelete}>
+        <Popconfirm title={'确认删除?'} onConfirm={props.onDelete}>
+          <div className={classNames('button-delete', { show: deleteVisible })}>
             <CloseOutlined />
-          </Popconfirm>
-        </div>
+          </div>
+        </Popconfirm>
       </div>
       {!props.isLast ? (
         <div className="term-type-warp">

+ 5 - 4
src/pages/rule-engine/Scene/Save/terms/term.tsx

@@ -9,6 +9,7 @@ import type { TermsType } from '@/pages/rule-engine/Scene/typings';
 import { get, set } from 'lodash';
 import './index.less';
 import { Popconfirm } from 'antd';
+
 interface TermsProps {
   data: TermsType;
   pName: (number | string)[];
@@ -123,11 +124,11 @@ export default observer((props: TermsProps) => {
               ));
             }}
           </Observer>
-          <div className={classNames('terms-params-delete', { show: deleteVisible })}>
-            <Popconfirm title={'确认删除?'} onConfirm={props.onDelete}>
+          <Popconfirm title={'确认删除?'} onConfirm={props.onDelete}>
+            <div className={classNames('terms-params-delete', { show: deleteVisible })}>
               <CloseOutlined />
-            </Popconfirm>
-          </div>
+            </div>
+          </Popconfirm>
         </div>
         {!props.isLast ? (
           <div className="term-type-warp">

+ 80 - 35
src/pages/rule-engine/Scene/Save/timer/index.tsx

@@ -6,8 +6,14 @@ import { FormModel } from '@/pages/rule-engine/Scene/Save';
 import TimerTrigger from './TimerTrigger';
 import Action from '../action';
 import classNames from 'classnames';
+import { Form, FormInstance } from 'antd';
+import { TitleComponent } from '@/components';
 
-export default observer(() => {
+interface Props {
+  form: FormInstance;
+}
+
+export default observer((props: Props) => {
   const [visible, setVisible] = useState<boolean>(false);
 
   const handleLabel = (options: any): ReactChild | ReactChild[] => {
@@ -27,26 +33,41 @@ export default observer(() => {
   };
 
   return (
-    <div>
-      <div style={{ marginBottom: 16 }}>
+    <div style={{ marginBottom: 24 }}>
+      <div>
         <Observer>
           {() => {
             const label = handleLabel(FormModel.current.options?.trigger);
             return (
-              <AddButton
-                style={{ width: '100%' }}
-                onClick={() => {
-                  setVisible(true);
-                }}
+              <Form.Item
+                label={<TitleComponent style={{ fontSize: 14 }} data={'定时触发'} />}
+                name={'timer'}
+                rules={[
+                  {
+                    validator(_, v) {
+                      if (!v) {
+                        return Promise.reject(new Error('请配置定时触发规则'));
+                      }
+                      return Promise.resolve();
+                    },
+                  },
+                ]}
               >
-                <div
-                  className={classNames('trigger-options-content', {
-                    'is-add': !!Object.keys(FormModel.current.options?.trigger || {}).length,
-                  })}
+                <AddButton
+                  style={{ width: '100%' }}
+                  onClick={() => {
+                    setVisible(true);
+                  }}
                 >
-                  {label}
-                </div>
-              </AddButton>
+                  <div
+                    className={classNames('trigger-options-content', {
+                      'is-add': !!Object.keys(FormModel.current.options?.trigger || {}).length,
+                    })}
+                  >
+                    {label}
+                  </div>
+                </AddButton>
+              </Form.Item>
             );
           }}
         </Observer>
@@ -54,26 +75,48 @@ export default observer(() => {
       <div>
         <Observer>
           {() => (
-            <Action
-              thenOptions={FormModel.current.branches ? FormModel.current.branches[0].then : []}
-              name={0}
-              onAdd={(data) => {
-                if (FormModel.current.branches && data) {
-                  FormModel.current.branches[0].then = [
-                    ...FormModel.current.branches[0].then,
-                    data,
-                  ];
-                }
-              }}
-              onUpdate={(data, type) => {
-                const indexOf = FormModel.current.branches![0].then.findIndex(
-                  (item) => item.parallel === type,
-                );
-                if (indexOf !== -1) {
-                  FormModel.current.branches![0].then[indexOf] = data;
-                }
-              }}
-            />
+            <Form.Item
+              name={['branches', 0, 'then']}
+              rules={[
+                {
+                  validator(_, v) {
+                    if (v && !v.length) {
+                      return Promise.reject('至少配置一个执行动作');
+                    }
+                    return Promise.resolve();
+                  },
+                },
+              ]}
+            >
+              <Action
+                thenOptions={FormModel.current.branches ? FormModel.current.branches[0].then : []}
+                name={0}
+                onAdd={(data) => {
+                  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) => {
+                  const indexOf = FormModel.current.branches![0].then.findIndex(
+                    (item) => item.parallel === type,
+                  );
+                  if (indexOf !== -1) {
+                    if (data.actions?.length) {
+                      FormModel.current.branches![0].then[indexOf] = data;
+                    } else {
+                      FormModel.current.branches![0].then = [];
+                    }
+                    props.form.setFieldValue(
+                      ['branches', 0, 'then'],
+                      FormModel.current.branches![0].then,
+                    );
+                  }
+                }}
+              />
+            </Form.Item>
           )}
         </Observer>
       </div>
@@ -84,6 +127,8 @@ export default observer(() => {
             setVisible(false);
             FormModel.current.options!['trigger'] = options;
             FormModel.current.trigger!.timer = data;
+            props.form.setFieldValue('timer', data);
+            props.form.validateFields(['timer']);
           }}
           close={() => {
             setVisible(false);