瀏覽代碼

fix: bug#8864、8758、8759、8767

xieyonghong 3 年之前
父節點
當前提交
e98cee69f9

+ 6 - 2
src/app.tsx

@@ -195,11 +195,15 @@ export const request: RequestConfig = {
         .text()
         .then((resp: string) => {
           if (resp) {
+            let respObj: any = {};
+            try {
+              respObj = JSON.parse(resp || '{}');
+            } catch (e) {}
             notification.error({
               key: 'error',
-              message: JSON.parse(resp || '{}').message || '服务器内部错误!',
+              message: respObj.message || '服务器内部错误!',
             });
-            if (JSON.parse(resp || '{}').code === 'license required') {
+            if (respObj.code === 'license required') {
               //判断按钮权限
               let buttons = {};
               const buttonString = localStorage.getItem('MENUS_BUTTONS_CACHE');

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

@@ -74,6 +74,7 @@ export default observer((props: Props) => {
         addonAfter={TimeTypeAfter}
         style={{ maxWidth: 220 }}
         value={value}
+        precision={0}
         onChange={(v) => setValue(v!)}
         min={0}
         max={59}

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

@@ -20,7 +20,35 @@ interface FilterProps {
   onDelete: () => void;
 }
 
-const DoubleFilter = ['nbtw', 'btw'];
+const handleName = (_data: any) => (
+  <Space>
+    {_data.name}
+    <div style={{ color: 'grey', marginLeft: '5px' }}>{_data.fullName}</div>
+    {_data.description && (
+      <div style={{ color: 'grey', marginLeft: '5px' }}>({_data.description})</div>
+    )}
+  </Space>
+);
+//
+// const handleOptions = (options: any[]): any[] => {
+//   if (!options) return []
+//
+//   return options.map(item => {
+//     const disabled = item.children?.length > 0;
+//     return {
+//       ...item,
+//       column: item.column,
+//       key: item.column,
+//       value: item.column,
+//       title: handleName(item),
+//       disabled: disabled,
+//       children: handleOptions(item.children),
+//     };
+//   })
+// }
+
+const DoubleFilter = ['nbtw', 'btw', 'in', 'nin'];
+const columnOptionsMap = new Map<string, any>();
 export default observer((props: FilterProps) => {
   const [value, setValue] = useState<Partial<TermsVale> | undefined>({});
   const [termType, setTermType] = useState('');
@@ -65,21 +93,22 @@ export default observer((props: FilterProps) => {
     setValueType(node.dataType || node.type);
   };
 
-  const handleName = (data: any) => {
-    return (
-      <Space>
-        {data.name}
-        {data.description && (
-          <div style={{ color: 'grey', marginLeft: '5px' }}>({data.description})</div>
-        )}
-      </Space>
-    );
+  const convertLabelValue = (columnValue?: string) => {
+    if (columnValue) {
+      console.log(columnOptionsMap, columnValue);
+      const labelOptions = columnOptionsMap.get(columnValue);
+      const _termTypeOptions: any[] =
+        labelOptions?.termTypes?.map((tItem: any) => ({ title: tItem.name, key: tItem.id })) || [];
+      setTtOptions(_termTypeOptions);
+      setValueType(labelOptions?.type);
+    }
   };
 
   const handleTreeData = (data: any): any[] => {
     if (data.length > 0) {
       return data.map((item: any) => {
         const name = handleName(item);
+        columnOptionsMap.set(item.column, item);
         if (item.children) {
           return {
             ...item,
@@ -96,23 +125,25 @@ export default observer((props: FilterProps) => {
     return [];
   };
 
-  const getParams = () => {
+  const getParams = useCallback(() => {
     const _params = {
       branch: props.thenName,
       branchGroup: props.branchGroup,
       action: props.action,
     };
+    columnOptionsMap.clear();
     queryBuiltInParams(FormModel.current, _params).then((res: any) => {
       if (res.status === 200) {
         const params = handleTreeData(
           // res.result.filter((item: any) => !item.id.includes(`action_${props.action}`)),
-          res.result
+          res.result,
         );
         setColumnOptions(params);
         setBuiltInOptions(params);
+        convertLabelValue(props.data?.column);
       }
     });
-  };
+  }, [props.data?.column]);
 
   const handleOptionsLabel = (c: string, t: string, v: any) => {
     const termsTypeKey = {
@@ -126,6 +157,8 @@ export default observer((props: FilterProps) => {
       nbtw: '不在_value和_value2之间',
       time_gt_now: '距离当前时间大于_value秒',
       time_lt_now: '距离当前时间小于_value秒',
+      in: '在_value,_value2之中',
+      nin: '不在_value,_value2之中',
     };
 
     if (DoubleFilter.includes(t)) {
@@ -148,9 +181,9 @@ export default observer((props: FilterProps) => {
     if (props.data) {
       setColumn(props.data.column || '');
       setTermType(props.data.termType || '');
-      console.log('valueChange-filter-effect', props.data.value);
       setValue(props.data.value);
       ValueRef.current = props.data || {};
+      convertLabelValue(props.data.column);
     }
   }, [props.data]);
 
@@ -250,12 +283,15 @@ export default observer((props: FilterProps) => {
                 showLabelKey="fullName"
                 name={0}
                 onChange={(v, lb) => {
-                  setValue({
-                    ...v,
-                  });
+                  const _myValue = {
+                    value: [v.value, ValueRef.current.value?.value?.[1]],
+                    source: v.source,
+                  };
+                  ValueRef.current.value = _myValue;
+                  setValue(_myValue);
                   label[2] = { ...label[2], 0: lb };
                   setLabel([...label]);
-                  valueEventChange(v);
+                  valueEventChange(_myValue);
                 }}
               />
               <ParamsDropdown
@@ -268,12 +304,15 @@ export default observer((props: FilterProps) => {
                 showLabelKey="fullName"
                 name={1}
                 onChange={(v, lb) => {
-                  setValue({
-                    ...v,
-                  });
+                  const _myValue = {
+                    value: [ValueRef.current.value?.value?.[0], v.value],
+                    source: v.source,
+                  };
+                  ValueRef.current.value = _myValue;
+                  setValue(_myValue);
                   label[2] = { ...label[2], 1: lb };
                   setLabel([...label]);
-                  valueEventChange(v);
+                  valueEventChange(_myValue);
                 }}
               />
             </>

+ 40 - 26
src/pages/rule-engine/Scene/Save/components/Buttons/Dropdown.tsx

@@ -1,8 +1,9 @@
-import { useEffect, useMemo, useState } from 'react';
+import { useCallback, useEffect, useMemo, useState } from 'react';
 import { Dropdown, Tree } from 'antd';
 import classNames from 'classnames';
 import styles from './index.less';
 import { onlyMessage } from '@/utils/util';
+import { useOption } from '@/pages/rule-engine/Scene/Save/components/Buttons/index';
 
 type DropdownButtonOptions = {
   title: string;
@@ -33,11 +34,26 @@ const TypeStyle = {
 const DropdownButton = (props: DropdownButtonProps) => {
   const [myValue, setMyValue] = useState(props.value);
   const [label, setLabel] = useState('');
-  const [, setLoading] = useState(false);
+  // const [, setLoading] = useState(false);
   const [open, setOpen] = useState(false);
 
   const typeClassName = TypeStyle[props.type];
 
+  const { paramOptions, valueOptions } = useOption(props.options, props.fieldNames?.value);
+
+  const convertLabelValue = useCallback(
+    (key?: string) => {
+      if (key && paramOptions.length) {
+        const labelOptions = valueOptions.get(key);
+        const nameKey = props.showLabelKey || 'title';
+        setLabel(labelOptions[nameKey]);
+      } else {
+        setLabel(key!);
+      }
+    },
+    [paramOptions, valueOptions, props.fieldNames],
+  );
+
   const menuOnSelect = ({ key, item }: { key: string; item: any }) => {
     setOpen(false);
 
@@ -84,39 +100,37 @@ const DropdownButton = (props: DropdownButtonProps) => {
 
   const _options = !props.isTree ? { menu: menuOptions } : { dropdownRender: () => DropdownRender };
 
-  const findLabel = (value: string, data: DropdownButtonOptions[]): boolean => {
-    let isLabel = false;
-    return data.some((item) => {
-      if (item.key === value) {
-        let titleKey = 'title';
-        if (props.showLabelKey) {
-          titleKey = props.showLabelKey;
-        }
-        setLabel(item[titleKey]);
-        setLoading(false);
-        isLabel = true;
-      } else if (item.children) {
-        isLabel = findLabel(value, item.children);
-      }
-      return isLabel;
-    });
-  };
+  // const findLabel = (value: string, data: DropdownButtonOptions[]): boolean => {
+  //   let isLabel = false;
+  //   return data.some((item) => {
+  //     if (item.key === value) {
+  //       let titleKey = 'title';
+  //       if (props.showLabelKey) {
+  //         titleKey = props.showLabelKey;
+  //       }
+  //       setLabel(item[titleKey]);
+  //       setLoading(false);
+  //       isLabel = true;
+  //     } else if (item.children) {
+  //       isLabel = findLabel(value, item.children);
+  //     }
+  //     return isLabel;
+  //   });
+  // };
 
   useEffect(() => {
     setMyValue(props.value);
     if (!props.value) {
       setLabel('');
     } else {
-      setLoading(true);
-      findLabel(props.value, props.options);
+      // setLoading(true);
+      // findLabel(props.value, props.options);
     }
+    convertLabelValue(props.value);
   }, [props.value]);
 
   useEffect(() => {
-    if (props.value) {
-      findLabel(props.value, props.options);
-      setLoading(true);
-    }
+    convertLabelValue(props.value);
   }, [props.options]);
 
   return (
@@ -133,7 +147,7 @@ const DropdownButton = (props: DropdownButtonProps) => {
           }
         }}
       >
-        {label || props.placeholder}
+        {label ? label : props.placeholder}
       </div>
     </Dropdown>
   );

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

@@ -7,7 +7,7 @@ import moment from 'moment';
 import ParamsSelect from '../ParamsSelect';
 import './index.less';
 
-interface ParamsDropdownProps {
+export interface ParamsDropdownProps {
   value?: any;
   source?: string;
   placeholder?: string;
@@ -72,7 +72,6 @@ export default (props: ParamsDropdownProps) => {
         value: value,
         source: activeKey,
       };
-      setOpen(false)
       props.onChange?.(changeValue, _label);
     },
     [activeKey],
@@ -101,7 +100,16 @@ export default (props: ParamsDropdownProps) => {
             />
           );
         case 'enum':
-          return <Menus value={_value} options={props.options} onChange={onValueChange} />;
+          return (
+            <Menus
+              value={_value}
+              options={props.options}
+              onChange={(v, l) => {
+                onValueChange(v, l);
+                setOpen(false);
+              }}
+            />
+          );
         case 'boolean':
           const _options = [
             { label: '是', value: 'true', key: 'true' },
@@ -113,7 +121,7 @@ export default (props: ParamsDropdownProps) => {
               options={_options}
               onChange={(v, l) => {
                 onValueChange(v === 'true' ? true : false, l);
-                setOpen(false)
+                setOpen(false);
               }}
             />
           );
@@ -122,9 +130,8 @@ export default (props: ParamsDropdownProps) => {
             <MTimePicker
               value={_value ? moment(_value, 'HH:mm:ss') : undefined}
               onChange={(_: any, timeString: string) => {
-                console.log('timeString', timeString);
                 onValueChange(timeString, timeString);
-                setOpen(false)
+                setOpen(false);
               }}
             />
           );
@@ -139,7 +146,7 @@ export default (props: ParamsDropdownProps) => {
                     titleKey = props.showLabelKey;
                   }
                   onValueChange(selectedKeys[0], e.node[titleKey]);
-                  setOpen(false)
+                  setOpen(false);
                 }}
                 style={{ width: 300 }}
                 treeData={props.BuiltInOptions}
@@ -179,36 +186,48 @@ export default (props: ParamsDropdownProps) => {
     });
   };
 
-  useEffect(() => {
-    if (props.value?.value === undefined || props.value?.value === '') {
+  const valueLabel = useCallback(
+    (v: any, type: string) => {
+      console.log(type, v);
+      switch (type) {
+        case 'boolean':
+          setLabel(v ? '是' : '否');
+          break;
+        case 'enum':
+        case 'object':
+          findLabel(v, props.options || []);
+          break;
+        case 'built':
+          findLabel(v, props.BuiltInOptions || []);
+          break;
+        default:
+          setLabel(v);
+      }
+    },
+    [props.options, props.BuiltInOptions],
+  );
+
+  const initData = useCallback(() => {
+    let _value = props.value?.value;
+    if ('name' in props) {
+      _value = props.value?.value[props.name!];
+    }
+    console.log('initData', _value);
+    setMyValue(_value);
+    if (_value === undefined || _value === '') {
       setLabel('');
-    } else if (props.valueType === 'boolean') {
-      if (props.name) {
-        if (props.value.value[props.name] === true) {
-          setLabel('是');
-        } else if (props.value.value[props.name] === false) {
-          setLabel('否');
-        } else {
-          setLabel('');
-        }
+    } else {
+      if (props.BuiltInOptions && props.value.source === 'upper') {
+        valueLabel(_value, 'built');
       } else {
-        if (props.value.value === true) {
-          setLabel('是');
-        } else if (props.value.value === false) {
-          setLabel('否');
-        } else {
-          setLabel('');
-        }
+        valueLabel(_value, props.valueType);
       }
-    } else if (['enum', 'boolean'].includes(props.valueType)) {
-      setLabel(props.name ? props.value.value[props.name] : props.value.value);
-    } else if (props.BuiltInOptions) {
-      findLabel(props.value?.value, props.BuiltInOptions || []);
-    } else {
-      setLabel(props.value?.value);
     }
+  }, [props.value, props.options, props.valueType, props.BuiltInOptions]);
+
+  useEffect(() => {
+    initData();
     console.log('valueChange-params-effect', props.value?.source, props.value?.value);
-    setMyValue(props.value?.value);
     if (props.value?.source) {
       setActiveKey(props.value?.source);
     } else {
@@ -218,7 +237,11 @@ export default (props: ParamsDropdownProps) => {
 
   useEffect(() => {
     if (props.BuiltInOptions) {
-      findLabel(props.value?.value, props.BuiltInOptions || []);
+      let _value = props.value.value;
+      if ('name' in props) {
+        _value = props.value?.value[props.name!];
+      }
+      findLabel(_value, props.BuiltInOptions || []);
     }
   }, [props.BuiltInOptions]);
 

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

@@ -2,3 +2,4 @@ import './index.less';
 export { default as AddButton } from './AddButton';
 export { default as DropdownButton } from './Dropdown';
 export { default as ParamsDropdown } from './ParamsDropdown';
+export { default as useOption } from './useOption';

+ 32 - 0
src/pages/rule-engine/Scene/Save/components/Buttons/useOption.tsx

@@ -0,0 +1,32 @@
+import { useMemo } from 'react';
+
+interface OptionsProps {
+  paramOptions: any[];
+  valueOptions: Map<string, any>;
+}
+
+const useOptions = (options: any[], key?: any): OptionsProps => {
+  return useMemo(() => {
+    const _options = options;
+    const valueOptions = new Map<string, any>();
+
+    function dig(optionsList: any[]) {
+      optionsList.forEach((option) => {
+        const _key = key || 'key';
+        valueOptions.set(option[_key], option);
+        if (option.children) {
+          dig(option.children);
+        }
+      });
+    }
+
+    dig(_options);
+
+    return {
+      paramOptions: _options,
+      valueOptions: valueOptions,
+    };
+  }, [options, key]);
+};
+
+export default useOptions;

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

@@ -140,6 +140,7 @@ export default (props: TimmingTriggerProps) => {
                 placeholder={'请输入时间'}
                 addonAfter={TimeTypeAfter}
                 style={{ maxWidth: 170 }}
+                precision={0}
                 min={0}
                 max={59}
               />

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

@@ -226,7 +226,7 @@ export default observer((props: AddProps) => {
         Store.set('TriggerDeviceModel', {
           update: !isUpdate,
         });
-        console.log('isUpdate', isUpdate);
+        console.log('isUpdate', _options);
         props.onSave?.(saveData, _options);
       }
     }
@@ -293,7 +293,36 @@ export default observer((props: AddProps) => {
       }
     >
       <div className="steps-steps">
-        <Steps current={TriggerDeviceModel.stepNumber} items={TriggerDeviceModel.steps} />
+        <Steps
+          current={TriggerDeviceModel.stepNumber}
+          items={TriggerDeviceModel.steps}
+          onChange={(num) => {
+            if (num === 1) {
+              if (TriggerDeviceModel.productId) {
+                TriggerDeviceModel.stepNumber = num;
+              } else {
+                onlyMessage('请选择产品', 'error');
+              }
+            } else if (num === 2) {
+              if (
+                TriggerDeviceModel.selector === 'fixed' &&
+                !TriggerDeviceModel.selectorValues?.length
+              ) {
+                onlyMessage('请选择设备', 'error');
+                return;
+              } else if (
+                TriggerDeviceModel.selector === 'org' &&
+                !TriggerDeviceModel.selectorValues?.length
+              ) {
+                onlyMessage('请选择部门', 'error');
+                return;
+              }
+              TriggerDeviceModel.stepNumber = num;
+            } else {
+              TriggerDeviceModel.stepNumber = num;
+            }
+          }}
+        />
       </div>
       <div className="steps-content">
         {loading && renderComponent(TriggerDeviceModel.steps[TriggerDeviceModel.stepNumber]?.key)}

+ 3 - 2
src/pages/rule-engine/Scene/Save/device/product.tsx

@@ -239,7 +239,7 @@ export default observer(() => {
           type: 'radio',
           selectedRowKeys: [TriggerDeviceModel.productId],
           onChange: (_, selectedRows) => {
-            console.log('onChange',selectedRows);
+            console.log('onChange', selectedRows);
             TriggerDeviceModel.productId = selectedRows.map((item) => item.id)[0];
             TriggerDeviceModel.productDetail = selectedRows?.[0];
             handleMetadata(TriggerDeviceModel.productDetail.metadata);
@@ -250,7 +250,8 @@ export default observer(() => {
             TriggerDeviceModel.operation = {
               operator: 'online',
             };
-          }
+            TriggerDeviceModel.selectorValues = [];
+          },
         }}
         onPageChange={(page, size) => {
           TriggerDeviceModel.productPage = page;

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

@@ -7,14 +7,14 @@ import Timer from '../Save/timer/index';
 import { TitleComponent } from '@/components';
 import { observable } from '@formily/reactive';
 import { observer } from '@formily/react';
-import type { FormModelType, ActionBranchesProps } from '@/pages/rule-engine/Scene/typings';
+import type { FormModelType } from '@/pages/rule-engine/Scene/typings';
 import { useEffect, useCallback } from 'react';
 import { service } from '@/pages/rule-engine/Scene';
 import './index.less';
-import { onlyMessage } from '@/utils/util';
+import { onlyMessage, randomString } from '@/utils/util';
 import { useHistory } from 'umi';
 import { getMenuPathByCode } from '@/utils/menu';
-import { cloneDeep } from 'lodash';
+import { cloneDeep, isArray } from 'lodash';
 
 export const defaultBranches = [
   {
@@ -33,7 +33,7 @@ export const defaultBranches = [
         key: 'terms_1',
       },
     ],
-    key: 'branckes_1',
+    key: 'branches_1',
     shakeLimit: {
       enabled: false,
       time: 0,
@@ -72,7 +72,7 @@ export default observer(() => {
   const triggerType = location?.query?.triggerType || '';
   const id = location?.query?.id || '';
   const history = useHistory();
-  const [form] = Form.useForm()
+  const [form] = Form.useForm();
 
   const FormModelInit = () => {
     FormModel.current = {
@@ -84,7 +84,7 @@ export default observer(() => {
         ...defaultBranches,
         {
           when: [],
-          key: 'branches_2',
+          key: 'branches_' + new Date().getTime(),
           shakeLimit: {
             enabled: false,
             time: 0,
@@ -97,7 +97,24 @@ export default observer(() => {
     };
   };
 
+  const assignmentKey = (data: any[]): any[] => {
+    const onlyKey = ['when', 'then', 'terms', 'actions'];
+    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]);
+        }
+      });
+
+      return item;
+    });
+  };
+
   useEffect(() => {
+    window.scrollTo(0, 0);
     return () => {
       // 销毁
       console.log('销毁');
@@ -111,44 +128,12 @@ export default observer(() => {
       service.detail(id).then((resp) => {
         if (resp.status === 200) {
           console.log('defaultBranches', defaultBranches);
-          let branches = resp.result.branches || cloneDeep(defaultBranches);
-          // 处理 branches 的 key
-          if (branches) {
-            branches = branches.map((bItem: ActionBranchesProps, bIndex: number) => {
-              if (!bItem.key) {
-                bItem.key = `branches_${new Date().getTime() + bIndex}`;
-                if (bItem.then && bItem.then.length) {
-                  bItem.then = bItem.then.map((tItem,tIndex) => {
-                    tItem.key = `then_${new Date().getTime() + tIndex}`;
-                    if (tItem.actions) {
-                      tItem.actions = tItem.actions.map((aItem, index) => {
-                        aItem.key = `${aItem.executor}_${new Date().getTime() + index}`;
-                        return aItem;
-                      });
-                    }
-                    return tItem;
-                  });
-                }
-                if (bItem.when && bItem.when.length) {
-                  bItem.when = bItem.when.map((wItem, index) => {
-                    wItem.key = `when_${new Date().getTime() + index}`;
-                    if (wItem.terms) {
-                      wItem.terms = wItem.terms.map((wtItem, wtIndex) => {
-                        wtItem.key = `terms_${new Date().getTime() + wtIndex}`;
-                        return wtItem;
-                      });
-                    }
-                    return wItem;
-                  });
-                }
-              }
-              return bItem;
-            });
-          }
+          const branches = resp.result.branches || defaultBranches;
           if (branches[0]?.when?.length) {
+            // 设备
             branches.push({
               when: [],
-              key: 'branckes_2',
+              key: 'branches_' + new Date().getTime(),
               shakeLimit: {
                 enabled: false,
                 time: 0,
@@ -163,9 +148,9 @@ export default observer(() => {
           };
           FormModel.current.options = { ...defaultOptions, ...resp.result.options };
           FormModel.current.trigger = resp.result.trigger || {};
-          FormModel.current.branches = branches;
+          FormModel.current.branches = cloneDeep(assignmentKey(branches));
 
-          form.setFieldValue('description', resp.result.description)
+          form.setFieldValue('description', resp.result.description);
         }
       });
     }
@@ -198,7 +183,7 @@ export default observer(() => {
   };
 
   const submit = useCallback(() => {
-    const baseData = form.getFieldsValue()
+    const baseData = form.getFieldsValue();
     const FormData = cloneDeep(FormModel.current);
     const { options, branches } = FormData;
     if (options?.terms) {
@@ -216,10 +201,10 @@ export default observer(() => {
     }
 
     if (baseData) {
-      FormData.description = baseData.description
+      FormData.description = baseData.description;
     }
 
-    service.updateScene(FormData).then((res) => {
+    service.updateScene(FormData).then((res: any) => {
       if (res.status === 200) {
         onlyMessage('操作成功', 'success');
         const url = getMenuPathByCode('rule-engine/Scene');

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

@@ -1,6 +1,10 @@
 import { useEffect, useState, useCallback, useRef } from 'react';
 import type { TermsType, TermsVale } from '@/pages/rule-engine/Scene/typings';
-import { DropdownButton, ParamsDropdown } from '@/pages/rule-engine/Scene/Save/components/Buttons';
+import {
+  DropdownButton,
+  ParamsDropdown,
+  useOption,
+} from '@/pages/rule-engine/Scene/Save/components/Buttons';
 import { CloseOutlined, PlusOutlined } from '@ant-design/icons';
 import classNames from 'classnames';
 import { observer } from '@formily/react';
@@ -20,16 +24,47 @@ interface ParamsItemProps {
   onDelete: () => void;
 }
 
-const DoubleFilter = ['nbtw', 'btw'];
+const handleName = (_data: any) => (
+  <Space>
+    {_data.name}
+    <div style={{ color: 'grey', marginLeft: '5px' }}>{_data.fullName}</div>
+    {_data.description && (
+      <div style={{ color: 'grey', marginLeft: '5px' }}>({_data.description})</div>
+    )}
+  </Space>
+);
+
+const handleOptions = (options: any[]): any[] => {
+  if (!options) return [];
+
+  return options.map((item) => {
+    const disabled = item.children?.length > 0;
+    return {
+      ...item,
+      column: item.column,
+      key: item.column,
+      value: item.column,
+      title: handleName(item),
+      disabled: disabled,
+      children: handleOptions(item.children),
+    };
+  });
+};
+
+const DoubleFilter = ['nbtw', 'btw', 'in', 'nin'];
 const ParamsItem = observer((props: ParamsItemProps) => {
   const [deleteVisible, setDeleteVisible] = useState(false);
-  const [paramOptions, setParamOptions] = useState<any[]>([]);
   const [ttOptions, setTtOptions] = useState<any[]>([]);
   const [valueOptions] = useState<any>(undefined);
   const [metricsOptions, setMetricsOptions] = useState<any[]>([]);
   const [valueType, setValueType] = useState('');
 
-  const [value, setValue] = useState<Partial<TermsVale> | undefined>({});
+  const { paramOptions, valueOptions: paramsValueOptions } = useOption(props.options, 'column');
+
+  const [value, setValue] = useState<Partial<TermsVale> | undefined>({
+    value: undefined,
+    source: 'fixed',
+  });
   const [termType, setTermType] = useState('');
   const [column, setColumn] = useState('');
   const [label, setLabel] = useState<any[]>([undefined, undefined, {}]);
@@ -61,90 +96,39 @@ const ParamsItem = observer((props: ParamsItemProps) => {
     [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);
-    if (node.metrics) {
-      // 指标值
-      const _metrics = node.metrics.map((mItem: any) => ({ title: mItem.name, key: mItem.id }));
-      setMetricsOptions(_metrics);
-    }
-  };
-
-  const findParams = (key: string, data: any[]): boolean => {
-    let has = false;
-    return data.some((item) => {
-      if (item.value === key) {
-        paramChange({ node: item });
-        has = true;
-      } else if (item.children) {
-        has = findParams(key, item.children);
+  const convertLabelValue = useCallback(
+    (columnValue?: string) => {
+      if (columnValue && paramOptions.length) {
+        console.log('paramsValueOptions ===>>', paramsValueOptions);
+        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);
+        }
       }
-      return has;
-    });
-  };
-
-  const handleName = (_data: any): any => (
-    <Space>
-      {_data.name}
-      <div style={{ color: 'grey', marginLeft: '5px' }}>{_data.fullName}</div>
-      {_data.description && (
-        <div style={{ color: 'grey', marginLeft: '5px' }}>({_data.description})</div>
-      )}
-    </Space>
+    },
+    [paramOptions, paramsValueOptions],
   );
 
-  const handleChildrenName = (_data: any[]): any[] => {
-    if (_data?.length > 0) {
-      return _data.map((it) => {
-        if (it.children) {
-          return {
-            ...it,
-            key: it.column,
-            value: it.column,
-            title: handleName(it),
-            disabled: true,
-            children: handleChildrenName(it.children),
-          };
-        }
-        return { ...it, key: it.column, title: handleName(it) };
-      });
-    } else {
-      return [];
-    }
-  };
-
   useEffect(() => {
-    console.log('paramsChange', props.data);
-
     setTermType(props.data.termType || '');
     setValue(props.data.value);
     setColumn(props.data.column || '');
     ValueRef.current = props.data || {};
+    convertLabelValue(props.data.column);
   }, [props.data]);
 
   useEffect(() => {
-    const _data = props.options.map((item: any) => {
-      const disabled = item.children?.length > 0;
-      return {
-        ...item,
-        column: item.column,
-        key: item.column,
-        value: item.column,
-        title: handleName(item),
-        disabled: disabled,
-        children: handleChildrenName(item.children),
-      };
-    });
-
-    setParamOptions(_data);
-
-    if (column) {
-      findParams(column, _data);
-    }
+    convertLabelValue(props.data.column);
   }, [props.options]);
 
   const handleOptionsLabel = useCallback(
@@ -160,6 +144,8 @@ const ParamsItem = observer((props: ParamsItemProps) => {
         nbtw: '不在_value和_value2之间',
         time_gt_now: '距离当前时间大于_value秒',
         time_lt_now: '距离当前时间小于_value秒',
+        in: '在_value,_value2之中',
+        nin: '不在_value,_value2之中',
       };
       const typeKey = {
         and: '并且',
@@ -196,7 +182,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
         }}
       >
         <DropdownButton
-          options={paramOptions}
+          options={handleOptions(paramOptions)}
           type="param"
           placeholder="请选择参数"
           value={column}
@@ -211,7 +197,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
               value: undefined,
               source: 'manual',
             });
-            paramChange(item);
+            // convertLabelValue(item);
             setColumn(_value!);
             ValueRef.current.column = _value!;
             const node = item.node;
@@ -261,7 +247,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
             ValueRef.current.termType = v;
             valueChange({
               column: props.data.column,
-              value: value as TermsVale,
+              value: _value as TermsVale,
               termType: v,
             });
           }}
@@ -277,12 +263,15 @@ const ParamsItem = observer((props: ParamsItemProps) => {
               value={value}
               name={0}
               onChange={(v, lb) => {
-                setValue({
-                  ...v,
-                });
+                const _myValue = {
+                  value: [v.value, ValueRef.current.value?.value?.[1]],
+                  source: v.source,
+                };
+                ValueRef.current.value = _myValue;
+                setValue(_myValue);
                 label[2] = { ...label[2], 0: lb };
                 setLabel([...label]);
-                valueEventChange(v);
+                valueEventChange(_myValue);
               }}
             />
             <ParamsDropdown
@@ -294,12 +283,15 @@ const ParamsItem = observer((props: ParamsItemProps) => {
               value={value}
               name={1}
               onChange={(v, lb) => {
-                setValue({
-                  ...v,
-                });
+                const _myValue = {
+                  value: [ValueRef.current.value?.value?.[0], v.value],
+                  source: v.source,
+                };
+                ValueRef.current.value = _myValue;
+                setValue(_myValue);
                 label[2] = { ...label[2], 1: lb };
                 setLabel([...label]);
-                valueEventChange(v);
+                valueEventChange(_myValue);
               }}
             />
           </>
@@ -316,7 +308,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
                 ...v,
               });
               label[2] = { 0: lb };
-
+              ValueRef.current.value = v;
               setLabel([...label]);
               valueEventChange(v);
             }}