xieyonghong пре 3 година
родитељ
комит
1857f1f0f3
23 измењених фајлова са 463 додато и 374 уклоњено
  1. 26 9
      src/components/ProTableCard/CardItems/Scene/index.tsx
  2. 2 2
      src/pages/rule-engine/Scene/Save/action/Delay/index.tsx
  3. 26 61
      src/pages/rule-engine/Scene/Save/action/ListItem/FilterCondition.tsx
  4. 7 8
      src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx
  5. 2 3
      src/pages/rule-engine/Scene/Save/action/index.tsx
  6. 5 3
      src/pages/rule-engine/Scene/Save/components/Buttons/Dropdown.tsx
  7. 1 1
      src/pages/rule-engine/Scene/Save/components/Buttons/ParamsDropdown.tsx
  8. 2 2
      src/pages/rule-engine/Scene/Save/components/TimingTrigger/RangePicker.tsx
  9. 16 2
      src/pages/rule-engine/Scene/Save/components/TimingTrigger/TimePicker.tsx
  10. 1 1
      src/pages/rule-engine/Scene/Save/components/TimingTrigger/index.tsx
  11. 1 0
      src/pages/rule-engine/Scene/Save/device/TopCard.tsx
  12. 21 21
      src/pages/rule-engine/Scene/Save/device/addModel.tsx
  13. 40 1
      src/pages/rule-engine/Scene/Save/device/org.tsx
  14. 14 12
      src/pages/rule-engine/Scene/Save/device/type.tsx
  15. 31 55
      src/pages/rule-engine/Scene/Save/index.tsx
  16. 5 5
      src/pages/rule-engine/Scene/Save/manual/index.tsx
  17. 69 63
      src/pages/rule-engine/Scene/Save/terms/branchItem.tsx
  18. 20 7
      src/pages/rule-engine/Scene/Save/terms/index.less
  19. 61 20
      src/pages/rule-engine/Scene/Save/terms/index.tsx
  20. 76 74
      src/pages/rule-engine/Scene/Save/terms/paramsItem.tsx
  21. 10 5
      src/pages/rule-engine/Scene/Save/terms/term.tsx
  22. 22 17
      src/pages/rule-engine/Scene/Save/timer/TimerTrigger/index.tsx
  23. 5 2
      src/pages/rule-engine/Scene/Save/timer/index.tsx

+ 26 - 9
src/components/ProTableCard/CardItems/Scene/index.tsx

@@ -9,6 +9,8 @@ import { CheckOutlined, DownOutlined, UpOutlined } from '@ant-design/icons';
 import classNames from 'classnames';
 import { ActionsType, BranchesThen } from '@/pages/rule-engine/Scene/typings';
 import MyTooltip from './MyTooltip';
+import { handleOptionsLabel } from '@/pages/rule-engine/Scene/Save/terms/paramsItem';
+import { isArray } from 'lodash';
 
 const imageMap = new Map();
 imageMap.set('timer', require('/public/images/scene/scene-timer.png'));
@@ -284,16 +286,28 @@ const actionRender = (action: ActionsType, index: number) => {
 };
 
 const conditionsRender = (when: any[], index: number) => {
+  let whenStr: string = '';
   if (when.length && when[index]) {
-    let str: string = '';
-    (when[index]?.terms || []).map((i: any, _index: number) => {
-      str += `${i?.terms.join(' ') || ''}${
-        i?.termType && when[index]?.terms.length !== _index + 1 ? i?.termType : ''
-      }`;
+    const terms = when[index]?.terms || [];
+    const termsLength = terms.length;
+    terms.map((termsItem: any, tIndex: number) => {
+      const tLast = tIndex < termsLength - 1;
+      let tSer = '';
+      if (termsItem.terms) {
+        tSer = isArray(termsItem.terms)
+          ? termsItem.terms
+              .map((bTermItem: any, bIndex: number) => {
+                const bLast = bIndex < termsItem.terms.length - 1;
+                return handleOptionsLabel(bTermItem, bLast ? '' : bTermItem[3]);
+              })
+              .join('')
+          : '';
+        whenStr += tLast ? tSer : tLast + termsItem.termType;
+      }
     });
-    return str;
+    return whenStr;
   }
-  return '';
+  return whenStr;
 };
 
 const branchesActionRender = (actions: any[]) => {
@@ -311,7 +325,10 @@ const branchesActionRender = (actions: any[]) => {
           {actions[index]?.options?.terms && (
             <div className={'ellipsis'} style={{ minWidth: 40 }}>
               动作{index + 1}
-              {actions[index]?.options?.terms}
+              {handleOptionsLabel(
+                actions[index]?.options?.terms,
+                index < actions.length - 1 ? actions[index].terms?.[0]?.type : undefined,
+              )}
             </div>
           )}
         </MyTooltip>
@@ -431,7 +448,7 @@ const ContentRender = (data: SceneCardProps) => {
                           {(item?.then || []).map((i: BranchesThen, _index: number) => (
                             <div key={i?.key || _index} className={styles['right-item-right-item']}>
                               <div className={styles['trigger-ways']}>
-                                {i.parallel ? '并行执行' : '串行执行'}
+                                {i ? (i.parallel ? '并行执行' : '串行执行') : ''}
                               </div>
                               <div className={classNames(styles['right-item-right-item-contents'])}>
                                 {branchesActionRender(Array.isArray(i?.actions) ? i?.actions : [])}

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

@@ -74,10 +74,10 @@ export default observer((props: Props) => {
         addonAfter={TimeTypeAfter}
         style={{ maxWidth: 220 }}
         value={value}
-        precision={0}
+        precision={3}
         onChange={(v) => setValue(v!)}
         min={0}
-        max={59}
+        max={6535}
       />
     </Modal>
   );

+ 26 - 61
src/pages/rule-engine/Scene/Save/action/ListItem/FilterCondition.tsx

@@ -8,6 +8,7 @@ import { queryBuiltInParams } from '@/pages/rule-engine/Scene/Save/action/servic
 import '../index.less';
 import { FormModel } from '../..';
 import { Space } from 'antd';
+import { cloneDeep } from 'lodash';
 
 interface FilterProps {
   thenName: number;
@@ -15,7 +16,8 @@ interface FilterProps {
   action?: number;
   data?: TermsType;
   onChange: (value: TermsType) => void;
-  onLabelChange: (lb: string) => void;
+  onLabelChange: (lb: string[]) => void;
+  label?: any[];
   onAdd: () => void;
   onDelete: () => void;
 }
@@ -59,7 +61,7 @@ export default observer((props: FilterProps) => {
   const [ttOptions, setTtOptions] = useState<any>([]);
   const [valueOptions] = useState<any[]>([]);
   const [valueType, setValueType] = useState('');
-  const [label, setLabel] = useState<any[]>([undefined, undefined, {}]);
+  const labelCache = useRef<any[]>([undefined, undefined, {}]);
 
   const ValueRef = useRef<Partial<TermsType>>({
     column: '',
@@ -85,18 +87,11 @@ export default observer((props: FilterProps) => {
     [column, termType],
   );
 
-  const paramChange = (item: any) => {
-    const node = item.node;
-    const _termTypeOptions: any[] =
-      node.termTypes?.map((tItem: any) => ({ title: tItem.name, key: tItem.id })) || [];
-    setTtOptions(_termTypeOptions);
-    setValueType(node.dataType || node.type);
-  };
-
   const convertLabelValue = (columnValue?: string) => {
     if (columnValue) {
-      console.log('filter-convertLabelValue', columnOptionsMap, columnValue);
       const labelOptions = columnOptionsMap.get(columnValue);
+      if (!labelOptions) return;
+
       const _termTypeOptions: any[] =
         labelOptions?.termTypes?.map((tItem: any) => ({ title: tItem.name, key: tItem.id })) || [];
       setTtOptions(_termTypeOptions);
@@ -108,7 +103,7 @@ export default observer((props: FilterProps) => {
     if (data.length > 0) {
       return data.map((item: any) => {
         const name = handleName(item);
-        columnOptionsMap.set(item.column, item);
+        columnOptionsMap.set(item.id || item.column, item);
         if (item.children) {
           return {
             ...item,
@@ -132,7 +127,9 @@ export default observer((props: FilterProps) => {
       action: props.action,
     };
     columnOptionsMap.clear();
-    queryBuiltInParams(FormModel.current, _params).then((res: any) => {
+    const newData = cloneDeep(FormModel.current);
+    newData.branches = newData.branches?.filter((item) => !!item);
+    queryBuiltInParams(newData, _params).then((res: any) => {
       if (res.status === 200) {
         const params = handleTreeData(
           // res.result.filter((item: any) => !item.id.includes(`action_${props.action}`)),
@@ -145,40 +142,6 @@ export default observer((props: FilterProps) => {
     });
   }, [props.data?.column]);
 
-  const handleOptionsLabel = (c: string, t: string, v: any) => {
-    const termsTypeKey = {
-      eq: '等于_value',
-      neq: '不等于_value',
-      gt: '大于_value',
-      gte: '大于等于_value',
-      lt: '小于_value',
-      lte: '小于等于_value',
-      btw: '在_value和_value2之间',
-      nbtw: '不在_value和_value2之间',
-      time_gt_now: '距离当前时间大于_value秒',
-      time_lt_now: '距离当前时间小于_value秒',
-      in: '在_value,_value2之中',
-      nin: '不在_value,_value2之中',
-      like: '包含_value',
-      nlike: '不包含_value',
-    };
-
-    if (DoubleFilter.includes(t)) {
-      const str = termsTypeKey[t].replace('_value', v[0]).replace('_value2', v[1]);
-      return `${c} ${str}`;
-    }
-    const str = termsTypeKey[t].replace('_value', v);
-    return `${c} ${str}`;
-  };
-
-  useEffect(() => {
-    const _v = Object.values(label[2]);
-    if (_v.length && label[1]) {
-      const _l = handleOptionsLabel(label[0], label[1], _v.length > 1 ? _v : _v[0]);
-      props.onLabelChange?.(_l);
-    }
-  }, [label]);
-
   useEffect(() => {
     if (props.data) {
       setColumn(props.data.column || '');
@@ -195,12 +158,16 @@ export default observer((props: FilterProps) => {
     }
   }, []);
 
+  useEffect(() => {
+    labelCache.current = props.label || [undefined, undefined, {}];
+  }, [props.label]);
+
   return (
     <div className="filter-condition-warp">
       {props.data ? (
         <div className="filter-condition-content">
           <div
-            className={classNames('filter-condition-delete denger show')}
+            className={classNames('filter-condition-delete danger show')}
             onClick={props.onDelete}
           >
             <DeleteOutlined />
@@ -217,7 +184,7 @@ export default observer((props: FilterProps) => {
                 value: undefined,
                 source: 'fixed',
               });
-              paramChange(item);
+              // paramChange(item);
               setColumn(_value!);
               const node = item.node;
               const _termTypeOptions: any[] =
@@ -227,15 +194,14 @@ export default observer((props: FilterProps) => {
               let _termTypeValue = undefined;
               if (_termTypeOptions.length) {
                 _termTypeValue = _termTypeOptions[0].key;
-                label[1] = _termTypeValue;
+                labelCache.current[1] = _termTypeValue;
                 setTermType(_termTypeValue);
               } else {
-                label[1] = '';
+                labelCache.current[1] = '';
                 setTermType('');
               }
               ValueRef.current.column = _value!;
-              label[0] = node.fullName;
-              setLabel([...label]);
+              labelCache.current[0] = node.fullName;
               valueChange({
                 column: _value,
                 value: {
@@ -263,8 +229,7 @@ export default observer((props: FilterProps) => {
               setValue(_value);
               setTermType(v!);
 
-              label[1] = v;
-              setLabel([...label]);
+              labelCache.current[1] = v;
               ValueRef.current.termType = v;
               valueChange({
                 column: props.data!.column,
@@ -291,8 +256,8 @@ export default observer((props: FilterProps) => {
                   };
                   ValueRef.current.value = _myValue;
                   setValue(_myValue);
-                  label[2] = { ...label[2], 0: lb };
-                  setLabel([...label]);
+                  labelCache.current[2] = { ...labelCache.current[2], 0: lb };
+                  props.onLabelChange?.(labelCache.current);
                   valueEventChange(_myValue);
                 }}
               />
@@ -312,8 +277,8 @@ export default observer((props: FilterProps) => {
                   };
                   ValueRef.current.value = _myValue;
                   setValue(_myValue);
-                  label[2] = { ...label[2], 1: lb };
-                  setLabel([...label]);
+                  labelCache.current[2] = { ...labelCache.current[2], 1: lb };
+                  props.onLabelChange?.(labelCache.current);
                   valueEventChange(_myValue);
                 }}
               />
@@ -331,8 +296,8 @@ export default observer((props: FilterProps) => {
                 setValue({
                   ...v,
                 });
-                label[2] = { 0: lb };
-                setLabel([...label]);
+                labelCache.current[2] = { 0: lb };
+                props.onLabelChange?.(labelCache.current);
                 valueEventChange(v);
               }}
             />

+ 7 - 8
src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx

@@ -6,6 +6,7 @@ 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';
 
 export enum ParallelEnum {
   'parallel' = 'parallel',
@@ -304,6 +305,7 @@ export default (props: ItemProps) => {
           branchGroup={props.branchGroup}
           thenName={props.thenName}
           data={props.data.terms?.[0]}
+          label={props.data.options?.terms}
           onAdd={() => {
             let _data = props.data;
             if (!_data.terms) {
@@ -312,19 +314,16 @@ export default (props: ItemProps) => {
                 terms: [{}],
               };
               cacheValueRef.current = _data;
-              console.log('FilterCondition-add', _data);
               props.onUpdate(_data, op);
             }
           }}
           onChange={(termsData) => {
             const _data = props.data;
-            if (_data.terms) {
-              _data.terms = [termsData];
-              cacheValueRef.current = _data;
-              props.onUpdate(_data, {
-                ...op,
-              });
-            }
+            set(_data, 'terms', [termsData]);
+            cacheValueRef.current = _data;
+            props.onUpdate(_data, {
+              ...op,
+            });
           }}
           onLabelChange={(lb) => {
             props.onUpdate(cacheValueRef.current, {

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

@@ -26,7 +26,6 @@ export default (props: ActionsProps) => {
   useEffect(() => {
     setParallelArray(props.thenOptions.filter((item) => item.parallel));
     setSerialArray(props.thenOptions.filter((item) => !item.parallel));
-    console.log('action-effect', props.thenOptions);
   }, [props.thenOptions]);
 
   return (
@@ -72,7 +71,6 @@ export default (props: ActionsProps) => {
                 parallel={false}
                 actions={serialArray.length ? serialArray[0].actions : []}
                 onAdd={(actionItem) => {
-                  console.log('action-onAdd');
                   if (serialArray.length) {
                     const indexOf = serialArray[0].actions?.findIndex(
                       (aItem) => aItem.key === actionItem.key,
@@ -144,7 +142,8 @@ export default (props: ActionsProps) => {
                   if (aIndex !== -1) {
                     parallelArray[0].actions?.splice(aIndex, 1);
                     setParallelArray([...parallelArray]);
-                    props.onUpdate(serialArray[0], true);
+
+                    props.onUpdate(parallelArray[0], true);
                   }
                 }}
               />

+ 5 - 3
src/pages/rule-engine/Scene/Save/components/Buttons/Dropdown.tsx

@@ -45,13 +45,15 @@ const DropdownButton = (props: DropdownButtonProps) => {
     (key?: string) => {
       if (key && paramOptions.length) {
         const labelOptions = valueOptions.get(key);
-        const nameKey = props.showLabelKey || 'title';
-        setLabel(labelOptions[nameKey]);
+        if (labelOptions) {
+          const nameKey = props.showLabelKey || 'title';
+          setLabel(labelOptions[nameKey]);
+        }
       } else {
         setLabel(key!);
       }
     },
-    [paramOptions, valueOptions, props.fieldNames],
+    [paramOptions, valueOptions, props.fieldNames, props.showLabelKey],
   );
 
   const menuOnSelect = ({ key, item }: { key: string; item: any }) => {

+ 1 - 1
src/pages/rule-engine/Scene/Save/components/Buttons/ParamsDropdown.tsx

@@ -199,7 +199,7 @@ export default (props: ParamsDropdownProps) => {
           findLabel(v, props.BuiltInOptions || []);
           break;
         default:
-          setLabel(v);
+          setLabel(v + '');
       }
     },
     [props.options, props.BuiltInOptions],

+ 2 - 2
src/pages/rule-engine/Scene/Save/components/TimingTrigger/RangePicker.tsx

@@ -14,7 +14,7 @@ interface RangePickerProps {
   onChange?: (value: RangePickerValue) => void;
   id?: string;
   form?: FormInstance<any>;
-  name: (string | number)[];
+  name?: (string | number)[];
 }
 export default (props: RangePickerProps) => {
   return (
@@ -28,7 +28,7 @@ export default (props: RangePickerProps) => {
       ]}
       onChange={(_, dateString) => {
         if (props.onChange) {
-          const { every, unit } = props.form?.getFieldValue([...props.name]);
+          const { every, unit } = props.form?.getFieldValue([...props.name!]);
           console.log(every, unit);
           props.onChange({
             from: dateString[0],

+ 16 - 2
src/pages/rule-engine/Scene/Save/components/TimingTrigger/TimePicker.tsx

@@ -1,5 +1,6 @@
 import { TimePicker } from 'antd';
 import moment from 'moment';
+import { useEffect, useState } from 'react';
 
 type TimePickerValue = {
   time: string;
@@ -11,13 +12,26 @@ interface TimePickerProps {
   id?: string;
 }
 export default (props: TimePickerProps) => {
+  const [value, setValue] = useState<any>(moment(new Date(), 'HH:mm:ss'));
+
+  useEffect(() => {
+    if (props.value?.time) {
+      if (moment.isMoment(props.value?.time)) {
+        setValue(props.value?.time);
+      } else {
+        setValue(moment(props.value?.time, 'HH:mm:ss'));
+      }
+    }
+  }, [props.value?.time]);
+
   return (
     <TimePicker
       id={props.id}
       style={{ width: '100%' }}
       format={'HH:mm:ss'}
-      value={moment(props.value?.time || new Date(), 'HH:mm:ss')}
-      onChange={(_, dateString) => {
+      value={moment(value || new Date(), 'HH:mm:ss')}
+      onChange={(_v, dateString) => {
+        setValue(_v);
         if (props.onChange) {
           props.onChange({
             time: dateString,

+ 1 - 1
src/pages/rule-engine/Scene/Save/components/TimingTrigger/index.tsx

@@ -127,7 +127,7 @@ export default (props: TimmingTriggerProps) => {
         <ItemGroup style={{ gap: 16 }}>
           <Form.Item
             name={[...name, 'once']}
-            // initialValue={{ time: moment(new Date()).format('HH:mm:ss') }}
+            initialValue={{ time: moment(new Date()).format('HH:mm:ss') }}
           >
             <TimePicker />
           </Form.Item>

+ 1 - 0
src/pages/rule-engine/Scene/Save/device/TopCard.tsx

@@ -28,6 +28,7 @@ const TopCard = (props: Props) => {
       if (props.onChange) {
         props.onChange(_type);
       }
+      props.onSelect?.(_type);
     }
   };
 

+ 21 - 21
src/pages/rule-engine/Scene/Save/device/addModel.tsx

@@ -95,7 +95,6 @@ export default observer((props: AddProps) => {
   }, []);
 
   useEffect(() => {
-    console.log('productPage', props.value);
     if (props.value) {
       TriggerDeviceModel.selector = props.value.selector;
       TriggerDeviceModel.productId = props.value.productId;
@@ -112,8 +111,6 @@ export default observer((props: AddProps) => {
   }, [props.value]);
 
   useEffect(() => {
-    console.log('productPage', props.options);
-
     if (props.options) {
       TriggerDeviceModel.devicePage = props.options.devicePage;
       TriggerDeviceModel.devicePageSize = props.options.devicePageSize;
@@ -151,23 +148,27 @@ export default observer((props: AddProps) => {
 
     if (data.timer) {
       const _timer = data.timer;
-      _options.when =
-        _timer.when!.length === 0
-          ? '每天'
-          : `每${_timer
-              .when!.map((item) => {
-                if (_timer!.trigger === 'week') {
-                  return numberToString[item];
-                } else {
-                  return item + '号';
-                }
-              })
-              .join(',')}`;
-      if (_timer.once) {
-        _options.time = _timer.once;
-      } else if (_timer.period) {
-        _options.time = _timer.period.from + '-' + _timer.period.to;
-        _options.extraTime = `每${_timer.period.every}${timeUnitEnum[_timer.period.unit]}执行1次`;
+      if (_timer.trigger === 'cron') {
+        _options.time = _timer.cron;
+      } else {
+        _options.when =
+          _timer.when!.length === 0
+            ? '每天'
+            : `每${_timer
+                .when!.map((item) => {
+                  if (_timer!.trigger === 'week') {
+                    return numberToString[item];
+                  } else {
+                    return item + '号';
+                  }
+                })
+                .join(',')}`;
+        if (_timer.once) {
+          _options.time = _timer.once.time + ' 执行1次';
+        } else if (_timer.period) {
+          _options.time = _timer.period.from + '-' + _timer.period.to;
+          _options.extraTime = `每${_timer.period.every}${timeUnitEnum[_timer.period.unit]}执行1次`;
+        }
       }
     }
 
@@ -226,7 +227,6 @@ export default observer((props: AddProps) => {
         Store.set('TriggerDeviceModel', {
           update: !isUpdate,
         });
-        console.log('isUpdate', _options);
         props.onSave?.(saveData, _options);
       }
     }

+ 40 - 1
src/pages/rule-engine/Scene/Save/device/org.tsx

@@ -3,14 +3,22 @@ import SearchComponent from '@/components/SearchComponent';
 import { TriggerDeviceModel } from './addModel';
 import type { DepartmentItem } from '@/pages/system/Department/typings';
 import { service } from '@/pages/system/Department';
-import { useState, useRef } from 'react';
+import { useState, useRef, useEffect } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import { observer } from '@formily/reactive-react';
 
+const orgOptions = new Map();
 export default observer(() => {
   const actionRef = useRef<ActionType>();
   const [sortParam, setSortParam] = useState<any>({ name: 'sortIndex', order: 'asc' });
   const [param, setParam] = useState({});
+  const [openKeys, setOpenKeys] = useState<any[]>([]);
+
+  useEffect(() => {
+    return () => {
+      orgOptions.clear();
+    };
+  }, []);
 
   const columns: ProColumns<DepartmentItem>[] = [
     {
@@ -26,6 +34,25 @@ export default observer(() => {
     },
   ];
 
+  const handleOptions = (data: any[]) => {
+    if (!data) return;
+    data.forEach((item) => {
+      orgOptions.set(item.id, { id: item.id, parentId: item.parentId });
+      if (item.children) {
+        handleOptions(item.children);
+      }
+    });
+  };
+
+  const findPid = (id: string, keys: string[]): string[] => {
+    const _item = orgOptions.get(id);
+    keys.push(_item.id);
+    if (_item.parentId) {
+      return findPid(_item.parentId, keys);
+    }
+    return keys;
+  };
+
   return (
     <>
       <SearchComponent<DepartmentItem>
@@ -52,6 +79,12 @@ export default observer(() => {
         scroll={{
           y: 350,
         }}
+        expandable={{
+          expandedRowKeys: openKeys,
+          onExpandedRowsChange: (keys) => {
+            setOpenKeys(keys as any[]);
+          },
+        }}
         rowSelection={{
           type: 'radio',
           selectedRowKeys: [TriggerDeviceModel.orgId],
@@ -81,6 +114,12 @@ export default observer(() => {
             sorts: [sortParam],
             ...params,
           });
+
+          handleOptions(response.result);
+          if (TriggerDeviceModel.orgId) {
+            const _openKeys = findPid(TriggerDeviceModel.orgId, []);
+            setOpenKeys(_openKeys);
+          }
           return {
             code: response.message,
             result: {

+ 14 - 12
src/pages/rule-engine/Scene/Save/device/type.tsx

@@ -146,17 +146,6 @@ export default forwardRef((props: Props, ref) => {
     }
   }, [props.data]);
 
-  useEffect(() => {
-    if (TimeFilterArray.includes(operator)) {
-      form.setFieldsValue({
-        timer: {
-          trigger: 'week',
-          mod: 'period',
-        },
-      });
-    }
-  }, [operator]);
-
   useImperativeHandle(ref, () => ({
     validateFields: form.validateFields,
   }));
@@ -171,7 +160,20 @@ export default forwardRef((props: Props, ref) => {
     >
       <Form form={form} layout={'vertical'}>
         <Form.Item name="operator" label="触发类型" required initialValue={'online'}>
-          <TopCard typeList={TypeList} labelBottom={true} />
+          <TopCard
+            typeList={TypeList}
+            labelBottom={true}
+            onSelect={() => {
+              if (TimeFilterArray.includes(operator)) {
+                form.setFieldsValue({
+                  timer: {
+                    trigger: 'week',
+                    mod: 'period',
+                  },
+                });
+              }
+            }}
+          />
         </Form.Item>
         {TimeFilterArray.includes(operator) && <TimingTrigger name={['timer']} form={form} />}
         {operator === OperatorType.readProperty && (

+ 31 - 55
src/pages/rule-engine/Scene/Save/index.tsx

@@ -8,7 +8,7 @@ import { TitleComponent } from '@/components';
 import { observable } from '@formily/reactive';
 import { observer } from '@formily/react';
 import type { FormModelType } from '@/pages/rule-engine/Scene/typings';
-import { useEffect, useCallback } from 'react';
+import { useEffect, useCallback, useState } from 'react';
 import { service } from '@/pages/rule-engine/Scene';
 import './index.less';
 import { onlyMessage, randomString } from '@/utils/util';
@@ -73,6 +73,7 @@ export default observer(() => {
   const id = location?.query?.id || '';
   const history = useHistory();
   const [form] = Form.useForm();
+  const [saveLoading, setSaveLoading] = useState(false);
 
   const FormModelInit = () => {
     FormModel.current = {
@@ -80,20 +81,7 @@ export default observer(() => {
         type: '',
       },
       options: defaultOptions,
-      branches: [
-        ...defaultBranches,
-        {
-          when: [],
-          key: 'branches_' + new Date().getTime(),
-          shakeLimit: {
-            enabled: false,
-            time: 0,
-            threshold: 0,
-            alarmFirst: false,
-          },
-          then: [],
-        },
-      ],
+      branches: [...defaultBranches],
     };
   };
 
@@ -102,13 +90,14 @@ export default observer(() => {
     if (!data) return [];
 
     return data.map((item: any) => {
-      item.key = randomString();
-      Object.keys(item).some((key) => {
-        if (onlyKey.includes(key) && isArray(item[key])) {
-          item[key] = assignmentKey(item[key]);
-        }
-      });
-
+      if (item) {
+        item.key = randomString();
+        Object.keys(item).some((key) => {
+          if (onlyKey.includes(key) && isArray(item[key])) {
+            item[key] = assignmentKey(item[key]);
+          }
+        });
+      }
       return item;
     });
   };
@@ -127,43 +116,30 @@ export default observer(() => {
     if (id) {
       service.detail(id).then((resp) => {
         if (resp.status === 200) {
-          console.log('defaultBranches', defaultBranches);
-          const branches = resp.result.branches || defaultBranches;
-          if (resp.result.branches && !resp.result.branches.length) {
-            branches.push({
-              when: [],
-              key: 'branches_' + new Date().getTime(),
-              shakeLimit: {
-                enabled: false,
-                time: 0,
-                threshold: 0,
-                alarmFirst: false,
-              },
-              then: [],
-            });
+          let branches = resp.result.branches;
+          if (!branches) {
+            branches = defaultBranches;
+            if (resp.result.triggerType === 'device') {
+              branches.push(null);
+            }
           } else {
-            if (branches[0]?.when?.length) {
-              // 设备
-              branches.push({
-                when: [],
-                key: 'branches_' + new Date().getTime(),
-                shakeLimit: {
-                  enabled: false,
-                  time: 0,
-                  threshold: 0,
-                  alarmFirst: false,
-                },
-                then: [],
-              });
+            const branchesLength = branches.length;
+            if (
+              resp.result.triggerType === 'device' &&
+              ((branchesLength === 1 && !!branches[0]?.when?.length) || // 有一组数据并且when有值
+                (branchesLength > 1 && !branches[branchesLength - 1]?.when?.length)) // 有多组否则数据,并且最后一组when有值
+            ) {
+              branches.push(null);
             }
           }
+
           FormModel.current = {
             ...resp.result,
           };
+          const newBranches = cloneDeep(assignmentKey(branches));
           FormModel.current.options = { ...defaultOptions, ...resp.result.options };
           FormModel.current.trigger = resp.result.trigger || {};
-          FormModel.current.branches = cloneDeep(assignmentKey(branches));
-
+          FormModel.current.branches = newBranches;
           form.setFieldValue('description', resp.result.description);
         }
       });
@@ -209,16 +185,16 @@ export default observer(() => {
         delete options.terms;
       }
     }
-
     if (branches) {
-      FormData.branches = branches.filter((item) => !!item.then.length || !!item.when.length);
+      FormData.branches = branches.filter((item) => item);
     }
 
     if (baseData) {
       FormData.description = baseData.description;
     }
-
+    setSaveLoading(true);
     service.updateScene(FormData).then((res: any) => {
+      setSaveLoading(false);
       if (res.status === 200) {
         onlyMessage('操作成功', 'success');
         const url = getMenuPathByCode('rule-engine/Scene');
@@ -239,7 +215,7 @@ export default observer(() => {
             <Input.TextArea showCount maxLength={200} placeholder={'请输入说明'} rows={4} />
           </Form.Item>
           <Form.Item>
-            <Button type="primary" htmlType="submit" onClick={submit}>
+            <Button type="primary" htmlType="submit" onClick={submit} loading={saveLoading}>
               保存
             </Button>
           </Form.Item>

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

@@ -1,8 +1,8 @@
 import Action from '../action';
-import { Observer, observer } from '@formily/react';
+import { Observer } from '@formily/react';
 import { FormModel } from '@/pages/rule-engine/Scene/Save';
 
-export default observer(() => {
+export default () => {
   return (
     <div>
       <Observer>
@@ -11,8 +11,8 @@ export default observer(() => {
             thenOptions={FormModel.current.branches ? FormModel.current.branches[0].then : []}
             name={0}
             onAdd={(data) => {
-              if (FormModel.current.branches) {
-                FormModel.current.branches[0].then.push(data);
+              if (FormModel.current.branches && data) {
+                FormModel.current.branches[0].then = [...FormModel.current.branches[0].then, data];
               }
             }}
             onUpdate={(data, type) => {
@@ -28,4 +28,4 @@ export default observer(() => {
       </Observer>
     </div>
   );
-});
+};

+ 69 - 63
src/pages/rule-engine/Scene/Save/terms/branchItem.tsx

@@ -1,24 +1,27 @@
 import { observer, Observer } from '@formily/react';
 import { useState, useEffect } from 'react';
 import { FormModel } from '@/pages/rule-engine/Scene/Save';
-import { PlusCircleOutlined, DeleteOutlined } from '@ant-design/icons';
+import { PlusCircleOutlined, DeleteOutlined, CloseOutlined } from '@ant-design/icons';
 import type { ActionBranchesProps, TermsType } from '@/pages/rule-engine/Scene/typings';
 import Term from './term';
 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';
 interface BranchesItemProps {
   name: number;
   data: ActionBranchesProps;
   isFirst: boolean;
   paramsOptions: any[];
   onDelete: () => void;
+  onDeleteAll?: () => void;
 }
 
 export default observer((props: BranchesItemProps) => {
   const [when, setWhen] = useState<TermsType[]>([]);
   const [error, setError] = useState(false);
+  const [deleteVisible, setDeleteVisible] = useState(false);
 
   useEffect(() => {
     Store.subscribe('TriggerDeviceModel', (data) => {
@@ -55,17 +58,7 @@ export default observer((props: BranchesItemProps) => {
     });
     // 增加下一个否则, '当' 排除
     if (index > 0) {
-      FormModel.current.branches?.push({
-        when: [],
-        key: `branch_${new Date().getTime()}`,
-        shakeLimit: {
-          enabled: false,
-          time: 0,
-          threshold: 0,
-          alarmFirst: false,
-        },
-        then: [],
-      });
+      FormModel.current.branches?.push(null as any);
     }
   };
 
@@ -75,74 +68,87 @@ export default observer((props: BranchesItemProps) => {
       <div
         className={classNames('actions-terms-options', { border: !props.isFirst, error: error })}
       >
-        {!props.isFirst && props.data.when.length ? (
-          <div className={classNames('terms-params-delete denger show')} onClick={props.onDelete}>
-            <DeleteOutlined />
+        {!props.isFirst ? (
+          <div className={classNames('terms-params-delete danger show')}>
+            <Popconfirm title={'确认删除?'} onConfirm={props.onDelete}>
+              <DeleteOutlined />
+            </Popconfirm>
           </div>
         ) : null}
-        <div className="actions-terms-list">
-          <Observer>
-            {() =>
-              when.length ? (
-                when.map((item, dIndex) => (
-                  <Term
-                    whenName={props.name}
-                    pName={[props.name, 'when']}
-                    name={dIndex}
-                    data={item}
-                    key={item.key}
-                    paramsOptions={props.paramsOptions}
-                    isLast={dIndex === when!.length - 1}
-                    onValueChange={(data) => {
-                      console.log('onValueChange2', data);
-                      // FormModel.current.branches![props.name].when[dIndex] = {
-                      //   ...FormModel.current.branches![props.name].when[dIndex],
-                      //   ...data,
-                      // };
-                      set(FormModel.current.branches!, [props.name, 'when', dIndex], data);
-                    }}
-                    onLabelChange={(options) => {
-                      FormModel.current.options!.terms[props.name] = options;
-                    }}
-                    onDelete={() => {
-                      FormModel.current.branches![props.name].when.splice(dIndex, 1);
+        <div
+          className={classNames('actions-terms-list')}
+          onMouseOver={() => {
+            if (!props.isFirst && when.length) setDeleteVisible(true);
+          }}
+          onMouseOut={() => {
+            if (!props.isFirst && when.length) setDeleteVisible(false);
+          }}
+        >
+          <div className={classNames('terms-params-delete', { show: deleteVisible })}>
+            <Popconfirm
+              title={'该操作将清空其它所有否则条件,确认删除?'}
+              placement="topRight"
+              onConfirm={props.onDeleteAll}
+            >
+              <CloseOutlined />
+            </Popconfirm>
+          </div>
+          <div className="actions-terms-list-content">
+            <Observer>
+              {() =>
+                when.length ? (
+                  when.map((item, dIndex) => (
+                    <Term
+                      whenName={props.name}
+                      pName={[props.name, 'when']}
+                      name={dIndex}
+                      data={item}
+                      key={item.key}
+                      paramsOptions={props.paramsOptions}
+                      isLast={dIndex === when!.length - 1}
+                      onValueChange={(data) => {
+                        set(FormModel.current.branches!, [props.name, 'when', dIndex], data);
+                      }}
+                      onLabelChange={(options) => {
+                        FormModel.current.options!.terms[props.name] = options;
+                      }}
+                      onDelete={() => {
+                        FormModel.current.branches![props.name].when.splice(dIndex, 1);
+                      }}
+                    />
+                  ))
+                ) : (
+                  <span
+                    style={{
+                      fontSize: 14,
+                      color: '#2F54EB',
+                      cursor: 'pointer',
+                      padding: props.isFirst ? '16px 0' : 0,
                     }}
-                  />
-                ))
-              ) : (
-                <span
-                  style={{
-                    fontSize: 14,
-                    color: '#2F54EB',
-                    cursor: 'pointer',
-                    padding: props.isFirst ? '16px 0' : 0,
-                  }}
-                  onClick={() => addWhen(props.name)}
-                >
-                  {' '}
-                  <PlusCircleOutlined style={{ padding: 4 }} /> 添加过滤条件
-                </span>
-              )
-            }
-          </Observer>
+                    onClick={() => addWhen(props.name)}
+                  >
+                    {' '}
+                    <PlusCircleOutlined style={{ padding: 4 }} /> 添加过滤条件
+                  </span>
+                )
+              }
+            </Observer>
+          </div>
         </div>
         <div className="actions-branches">
           <Observer>
             {() => {
-              console.log('action-onAdd', FormModel.current.branches?.[props.name].then);
               return (
                 <Actions
                   openShakeLimit={true}
                   name={props.name}
                   thenOptions={props.data.then}
                   onAdd={(data) => {
-                    console.log('action-onAdd', data, FormModel.current.branches);
-                    if (FormModel.current.branches) {
+                    if (FormModel.current.branches && data) {
                       FormModel.current.branches[props.name].then = [
                         ...FormModel.current.branches[props.name].then,
                         data,
                       ];
-                      console.log('action-onAdd2', FormModel.current.branches[props.name].then);
                     }
                   }}
                   onUpdate={(data, type) => {

+ 20 - 7
src/pages/rule-engine/Scene/Save/terms/index.less

@@ -1,3 +1,9 @@
+@import '~antd/es/style/themes/default.less';
+
+.add-button-color {
+  color: @primary-color;
+}
+
 .deleteBtn() {
   position: absolute;
   top: -10px;
@@ -50,13 +56,20 @@
         border-radius: 2px;
       }
 
+      &.no-when {
+        flex: none;
+      }
+
       .actions-terms-list {
-        display: flex;
-        padding-top: 10px;
-        overflow-x: auto;
-        overflow-y: visible;
-        // flex-wrap: wrap;
-        row-gap: 16px;
+        position: relative;
+
+        .actions-terms-list-content {
+          display: flex;
+          padding-top: 10px;
+          overflow-x: auto;
+          overflow-y: visible;
+          row-gap: 16px;
+        }
       }
     }
   }
@@ -64,7 +77,7 @@
   .terms-params-delete {
     .deleteBtn();
 
-    &.denger {
+    &.danger {
       color: #e50012;
       background-color: rgba(229, 0, 18, 0.1);
     }

+ 61 - 20
src/pages/rule-engine/Scene/Save/terms/index.tsx

@@ -9,6 +9,9 @@ import { 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';
+import classNames from 'classnames';
+import { PlusCircleOutlined } from '@ant-design/icons';
+import { randomString } from '@/utils/util';
 
 interface TermsModelProps {
   columnOptions: any[];
@@ -24,32 +27,30 @@ export default observer(() => {
   useEffect(() => {
     if (FormModel.current.branches && FormModel.current.branches.length === 1) {
       setOpen(false);
+    } else {
+      setOpen(true);
     }
   }, [FormModel.current.branches]);
 
+  useEffect(() => {
+    return () => {
+      TermsModel.columnOptions = [];
+    };
+  }, []);
+
   const queryColumn = (data: TriggerType) => {
-    service.getParseTerm({ trigger: data }).then((res: any) => {
+    const newData: any = cloneDeep(data);
+    newData.branches = newData.branches?.filter((item: any) => !!item);
+    service.getParseTerm({ trigger: newData }).then((res: any) => {
       TermsModel.columnOptions = res;
     });
   };
 
   const openChange = (checked: boolean) => {
     setOpen(checked);
+    const key = randomString();
     if (checked) {
-      FormModel.current.branches = cloneDeep([
-        ...defaultBranches,
-        {
-          when: [],
-          key: 'branches_2',
-          shakeLimit: {
-            enabled: false,
-            time: 0,
-            threshold: 0,
-            alarmFirst: false,
-          },
-          then: [],
-        },
-      ]);
+      FormModel.current.branches = cloneDeep([...defaultBranches, null as any]);
       set(FormModel.current.options!, 'when', [
         {
           terms: [
@@ -63,7 +64,7 @@ export default observer(() => {
       FormModel.current.branches = [
         {
           when: [],
-          key: 'branches_' + new Date().getTime(),
+          key: 'branches_' + key,
           shakeLimit: {
             enabled: false,
             time: 0,
@@ -77,6 +78,22 @@ export default observer(() => {
     }
   };
 
+  const addBranches = () => {
+    const key = randomString();
+    const branchesLength = FormModel.current.branches!.length;
+    FormModel.current.branches![branchesLength - 1] = {
+      when: [],
+      key: key,
+      shakeLimit: {
+        enabled: false,
+        time: 0,
+        threshold: 0,
+        alarmFirst: false,
+      },
+      then: [],
+    };
+  };
+
   useEffect(() => {
     if (FormModel.current.trigger?.device) {
       queryColumn(FormModel.current.trigger);
@@ -104,7 +121,7 @@ export default observer(() => {
           {() =>
             FormModel.current.branches?.map((item, index) => {
               const isFirst = index === 0;
-              return (
+              return item ? (
                 <BranchItem
                   data={item}
                   isFirst={isFirst}
@@ -112,10 +129,34 @@ export default observer(() => {
                   key={item.key}
                   paramsOptions={TermsModel.columnOptions}
                   onDelete={() => {
-                    FormModel.current.branches?.splice(index, 1);
+                    if (FormModel.current.branches?.length === 2) {
+                      FormModel.current.branches?.splice(index, 1, null as any);
+                    } else {
+                      FormModel.current.branches?.splice(index, 1);
+                    }
                     FormModel.current.options?.when?.splice(index, 1);
                   }}
+                  onDeleteAll={() => {
+                    FormModel.current.branches?.splice(
+                      index,
+                      FormModel.current.branches!.length - 1,
+                      null as any,
+                    );
+                  }}
                 />
+              ) : (
+                <div className="actions-terms-warp" style={{ alignItems: 'center' }}>
+                  <div className="actions-terms-title" style={{ padding: 0 }}>
+                    否则
+                  </div>
+                  <div className={classNames('actions-terms-options no-when')}>
+                    <PlusCircleOutlined
+                      className={'add-button-color'}
+                      style={{ fontSize: 32 }}
+                      onClick={addBranches}
+                    />
+                  </div>
+                </div>
               );
             })
           }
@@ -126,8 +167,8 @@ export default observer(() => {
           name={0}
           thenOptions={FormModel.current.branches ? FormModel.current.branches[0].then : []}
           onAdd={(data) => {
-            if (FormModel.current.branches) {
-              FormModel.current.branches[0].then.push(data);
+            if (FormModel.current.branches && data) {
+              FormModel.current.branches[0].then = [...FormModel.current.branches[0].then, data];
             }
           }}
           onUpdate={(data, type) => {

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

@@ -9,7 +9,8 @@ import { CloseOutlined, PlusOutlined } from '@ant-design/icons';
 import classNames from 'classnames';
 import { observer } from '@formily/react';
 import './index.less';
-import { Space } from 'antd';
+import { Popconfirm, Space } from 'antd';
+import { isArray, isObject } from 'lodash';
 
 interface ParamsItemProps {
   data: TermsType;
@@ -19,7 +20,8 @@ interface ParamsItemProps {
   isDelete: boolean;
   options: any[];
   onValueChange?: (value: TermsType) => void;
-  onLabelChange?: (label: string) => void;
+  onLabelChange?: (label: string[]) => void;
+  label?: any[];
   onAdd: () => void;
   onDelete: () => void;
 }
@@ -52,6 +54,44 @@ const handleOptions = (options: any[]): any[] => {
 };
 
 const DoubleFilter = ['nbtw', 'btw', 'in', 'nin'];
+
+export const handleOptionsLabel = (data: any, type?: string) => {
+  if (isArray(data)) {
+    const c = data[0];
+    const t = data[1];
+    const v = data[2];
+    const termsTypeKey = {
+      eq: '等于_value',
+      neq: '不等于_value',
+      gt: '大于_value',
+      gte: '大于等于_value',
+      lt: '小于_value',
+      lte: '小于等于_value',
+      btw: '在_value和_value2之间',
+      nbtw: '不在_value和_value2之间',
+      time_gt_now: '距离当前时间大于_value秒',
+      time_lt_now: '距离当前时间小于_value秒',
+      in: '在_value,_value2之中',
+      nin: '不在_value,_value2之中',
+      like: '包含_value',
+      nlike: '不包含_value',
+    };
+    const typeKey = {
+      and: '并且',
+      or: '或者',
+    };
+    const _value = isObject(v) ? Object.values(v) : [v];
+    const typeStr = type ? typeKey[type] : '';
+    if (DoubleFilter.includes(t)) {
+      const str = termsTypeKey[t].replace('_value', _value[0]).replace('_value2', _value[1]);
+      return `${c} ${str} ${typeStr}`;
+    }
+    const str = termsTypeKey[t].replace('_value', _value[0]);
+    return `${c} ${str} ${typeStr}`;
+  }
+  return data;
+};
+
 const ParamsItem = observer((props: ParamsItemProps) => {
   const [deleteVisible, setDeleteVisible] = useState(false);
   const [ttOptions, setTtOptions] = useState<any[]>([]);
@@ -67,7 +107,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
   });
   const [termType, setTermType] = useState('');
   const [column, setColumn] = useState('');
-  const [label, setLabel] = useState<any[]>([undefined, undefined, {}]);
+  const labelCache = useRef<any[]>([undefined, undefined, {}, 'and']);
 
   const ValueRef = useRef<Partial<TermsType>>({
     column: '',
@@ -77,7 +117,6 @@ const ParamsItem = observer((props: ParamsItemProps) => {
 
   const valueChange = useCallback(
     (_value: any) => {
-      console.log({ ..._value });
       props.onValueChange?.({ ..._value });
     },
     [column, termType, value],
@@ -85,8 +124,6 @@ const ParamsItem = observer((props: ParamsItemProps) => {
 
   const valueEventChange = useCallback(
     (_v: any) => {
-      console.log('valueEventChange', column, termType);
-
       valueChange({
         column: ValueRef.current.column,
         termType: ValueRef.current.termType,
@@ -99,20 +136,22 @@ const ParamsItem = observer((props: ParamsItemProps) => {
   const convertLabelValue = useCallback(
     (columnValue?: string) => {
       if (columnValue && paramOptions.length) {
-        console.log('paramsValueOptions ===>>', paramsValueOptions);
+        console.log('paramsValueOptions ===>>', paramsValueOptions, columnValue);
         const labelOptions = paramsValueOptions.get(columnValue);
-        const _termTypeOptions: any[] =
-          labelOptions?.termTypes?.map((tItem: any) => ({ title: tItem.name, key: tItem.id })) ||
-          [];
-        setTtOptions(_termTypeOptions);
-        setValueType(labelOptions.dataType);
-        if (labelOptions.metrics) {
-          // 指标值
-          const _metrics = labelOptions.metrics.map((mItem: any) => ({
-            title: mItem.name,
-            key: mItem.id,
-          }));
-          setMetricsOptions(_metrics);
+        if (labelOptions) {
+          const _termTypeOptions: any[] =
+            labelOptions?.termTypes?.map((tItem: any) => ({ title: tItem.name, key: tItem.id })) ||
+            [];
+          setTtOptions(_termTypeOptions);
+          setValueType(labelOptions.dataType);
+          if (labelOptions.metrics) {
+            // 指标值
+            const _metrics = labelOptions.metrics.map((mItem: any) => ({
+              title: mItem.name,
+              key: mItem.id,
+            }));
+            setMetricsOptions(_metrics);
+          }
         }
       }
     },
@@ -131,46 +170,10 @@ const ParamsItem = observer((props: ParamsItemProps) => {
     convertLabelValue(props.data.column);
   }, [props.options]);
 
-  const handleOptionsLabel = useCallback(
-    (c: string, t: string, v: any) => {
-      const termsTypeKey = {
-        eq: '等于_value',
-        neq: '不等于_value',
-        gt: '大于_value',
-        gte: '大于等于_value',
-        lt: '小于_value',
-        lte: '小于等于_value',
-        btw: '在_value和_value2之间',
-        nbtw: '不在_value和_value2之间',
-        time_gt_now: '距离当前时间大于_value秒',
-        time_lt_now: '距离当前时间小于_value秒',
-        in: '在_value,_value2之中',
-        nin: '不在_value,_value2之中',
-        like: '包含_value',
-        nlike: '不包含_value',
-      };
-      const typeKey = {
-        and: '并且',
-        or: '或者',
-      };
-      const typeStr = props.isLast ? '' : typeKey[props.data.type!];
-      if (DoubleFilter.includes(t)) {
-        const str = termsTypeKey[t].replace('_value', v[0]).replace('_value2', v[1]);
-        return `${c} ${str} ${typeStr}`;
-      }
-      const str = termsTypeKey[t].replace('_value', v);
-      return `${c} ${str} ${typeStr}`;
-    },
-    [props.isLast, props.data.type],
-  );
-
   useEffect(() => {
-    const _v = Object.values(label[2]);
-    if (_v.length && label[1]) {
-      const _l = handleOptionsLabel(label[0], label[1], _v.length > 1 ? _v : _v[0]);
-      props.onLabelChange?.(_l);
-    }
-  }, [label]);
+    console.log('params-effect', props.label);
+    labelCache.current = props.label || [undefined, undefined, {}, 'and'];
+  }, [props.label]);
 
   return (
     <div className="terms-params-item">
@@ -210,13 +213,12 @@ const ParamsItem = observer((props: ParamsItemProps) => {
             let _termTypeValue = undefined;
             if (_termTypeOptions.length) {
               _termTypeValue = _termTypeOptions[0].key;
-              label[1] = _termTypeValue;
+              labelCache.current[1] = _termTypeValue;
               setTermType(_termTypeValue);
             } else {
               setTermType('');
             }
-            label[0] = node.fullName;
-            setLabel([...label]);
+            labelCache.current[0] = node.fullName;
             valueChange({
               column: _value,
               value: {
@@ -244,8 +246,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
             setValue(_value);
             setTermType(v!);
 
-            label[1] = v;
-            setLabel([...label]);
+            labelCache.current[1] = v;
             ValueRef.current.termType = v;
             valueChange({
               column: props.data.column,
@@ -271,8 +272,8 @@ const ParamsItem = observer((props: ParamsItemProps) => {
                 };
                 ValueRef.current.value = _myValue;
                 setValue(_myValue);
-                label[2] = { ...label[2], 0: lb };
-                setLabel([...label]);
+                labelCache.current[2] = { ...labelCache.current[2], 0: lb };
+                props.onLabelChange?.([...labelCache.current, props.data.type]);
                 valueEventChange(_myValue);
               }}
             />
@@ -291,8 +292,8 @@ const ParamsItem = observer((props: ParamsItemProps) => {
                 };
                 ValueRef.current.value = _myValue;
                 setValue(_myValue);
-                label[2] = { ...label[2], 1: lb };
-                setLabel([...label]);
+                labelCache.current[2] = { ...labelCache.current[2], 1: lb };
+                props.onLabelChange?.([...labelCache.current, props.data.type]);
                 valueEventChange(_myValue);
               }}
             />
@@ -309,18 +310,18 @@ const ParamsItem = observer((props: ParamsItemProps) => {
               setValue({
                 ...v,
               });
-              label[2] = { 0: lb };
               ValueRef.current.value = v;
-              setLabel([...label]);
+              labelCache.current[2] = { 0: lb };
+              console.log('valueChange', labelCache.current);
+              props.onLabelChange?.([...labelCache.current, props.data.type]);
               valueEventChange(v);
             }}
           />
         )}
-        <div
-          className={classNames('button-delete', { show: deleteVisible })}
-          onClick={props.onDelete}
-        >
-          <CloseOutlined />
+        <div className={classNames('button-delete', { show: deleteVisible })}>
+          <Popconfirm title={'确认删除?'} onConfirm={props.onDelete}>
+            <CloseOutlined />
+          </Popconfirm>
         </div>
       </div>
       {!props.isLast ? (
@@ -335,6 +336,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
             value={props.data.type}
             onChange={(v) => {
               props.data.type = v;
+              props.onLabelChange?.([...labelCache.current, v]);
             }}
           />
         </div>

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

@@ -8,6 +8,7 @@ import classNames from 'classnames';
 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)[];
@@ -72,6 +73,11 @@ export default observer((props: TermsProps) => {
                   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]);
@@ -117,11 +123,10 @@ export default observer((props: TermsProps) => {
               ));
             }}
           </Observer>
-          <div
-            className={classNames('terms-params-delete', { show: deleteVisible })}
-            onClick={props.onDelete}
-          >
-            <CloseOutlined />
+          <div className={classNames('terms-params-delete', { show: deleteVisible })}>
+            <Popconfirm title={'确认删除?'} onConfirm={props.onDelete}>
+              <CloseOutlined />
+            </Popconfirm>
           </div>
         </div>
         {!props.isLast ? (

+ 22 - 17
src/pages/rule-engine/Scene/Save/timer/TimerTrigger/index.tsx

@@ -29,23 +29,28 @@ export default (props: Props) => {
     };
 
     const _timer = value;
-    _options.when =
-      _timer.when!.length === 0
-        ? '每天'
-        : `每${_timer
-            .when!.map((item) => {
-              if (_timer!.trigger === 'week') {
-                return numberToString[item];
-              } else {
-                return item + '号';
-              }
-            })
-            .join(',')}`;
-    if (_timer.once) {
-      _options.time = _timer.once;
-    } else if (_timer.period) {
-      _options.time = _timer.period.from + '-' + _timer.period.to;
-      _options.extraTime = `每${_timer.period.every}${timeUnitEnum[_timer.period.unit]}执行1次`;
+    if (_timer.trigger === 'cron') {
+      _options.time = _timer.cron;
+    } else {
+      _options.when =
+        _timer.when!.length === 0
+          ? '每天'
+          : `每${_timer
+              .when!.map((item) => {
+                if (_timer!.trigger === 'week') {
+                  return numberToString[item];
+                } else {
+                  return item + '号';
+                }
+              })
+              .join(',')}`;
+
+      if (_timer.once) {
+        _options.time = _timer.once.time + ' 执行1次';
+      } else if (_timer.period) {
+        _options.time = _timer.period.from + '-' + _timer.period.to;
+        _options.extraTime = `每${_timer.period.every}${timeUnitEnum[_timer.period.unit]}执行1次`;
+      }
     }
     return _options;
   };

+ 5 - 2
src/pages/rule-engine/Scene/Save/timer/index.tsx

@@ -58,8 +58,11 @@ export default observer(() => {
               thenOptions={FormModel.current.branches ? FormModel.current.branches[0].then : []}
               name={0}
               onAdd={(data) => {
-                if (FormModel.current.branches) {
-                  FormModel.current.branches[0].then.push(data);
+                if (FormModel.current.branches && data) {
+                  FormModel.current.branches[0].then = [
+                    ...FormModel.current.branches[0].then,
+                    data,
+                  ];
                 }
               }}
               onUpdate={(data, type) => {