瀏覽代碼

fix: bug#9342、9365

xieyonghong 3 年之前
父節點
當前提交
9de7f2dccb

+ 38 - 4
src/components/FMonacoEditor/index.tsx

@@ -1,11 +1,33 @@
 import MonacoEditor from 'react-monaco-editor';
 import MonacoEditor from 'react-monaco-editor';
 import { connect, mapProps } from '@formily/react';
 import { connect, mapProps } from '@formily/react';
-import { useRef, useState } from 'react';
+import { useCallback, useEffect, useRef, useState } from 'react';
+import type { MonacoEditorProps } from 'react-monaco-editor/lib/types';
 
 
-export const JMonacoEditor = (props: any) => {
+interface Props extends MonacoEditorProps {}
+
+export const JMonacoEditor = (props: Props) => {
   const [loading, setLoading] = useState(false);
   const [loading, setLoading] = useState(false);
+  const formatLock = useRef<boolean>(false);
   const monacoRef = useRef<any>();
   const monacoRef = useRef<any>();
-  console.log(props);
+  const monacoEditorRef = useRef<any>();
+
+  const editorFormat = (editor: any) => {
+    editor.getAction('editor.action.formatDocument').run();
+  };
+
+  useEffect(() => {
+    if (formatLock.current === false && monacoEditorRef.current) {
+      setTimeout(() => {
+        editorFormat(monacoEditorRef.current);
+      }, 300);
+      formatLock.current = true;
+    }
+  }, [props.value, loading, monacoEditorRef.current]);
+
+  const editorDidMountHandle = useCallback((editor: any, monaco: any) => {
+    monacoEditorRef.current = editor;
+    props.editorDidMount?.(editor, monaco);
+  }, []);
 
 
   return (
   return (
     <div
     <div
@@ -16,7 +38,19 @@ export const JMonacoEditor = (props: any) => {
       }}
       }}
       style={{ height: '100%', width: '100%' }}
       style={{ height: '100%', width: '100%' }}
     >
     >
-      {loading && <MonacoEditor ref={monacoRef} {...props} options={{ wordWrap: 'on' }} />}
+      {loading && (
+        <MonacoEditor
+          ref={(r: any) => {
+            monacoRef.current = r;
+            if (r && formatLock.current === false) {
+              editorFormat(r.editor);
+            }
+          }}
+          {...props}
+          options={{ wordWrap: 'on' }}
+          editorDidMount={editorDidMountHandle}
+        />
+      )}
     </div>
     </div>
   );
   );
 };
 };

+ 11 - 4
src/components/FRuleEditor/Advance/index.tsx

@@ -14,13 +14,14 @@ interface Props {
 }
 }
 
 
 const Advance = (props: Props) => {
 const Advance = (props: Props) => {
-  const { model, onChange, virtualRule } = props;
+  const { onChange, virtualRule } = props;
   const [success, setSuccess] = useState(false);
   const [success, setSuccess] = useState(false);
-  const cacheRef = useRef();
+  const [editorValue, setEditorValue] = useState(virtualRule.script);
+  const cacheRef = useRef(virtualRule.script);
   return (
   return (
     <Modal
     <Modal
       maskClosable={false}
       maskClosable={false}
-      visible={model === 'advance'}
+      visible
       width="70vw"
       width="70vw"
       title="设置属性规则"
       title="设置属性规则"
       onCancel={() => onChange('simple')}
       onCancel={() => onChange('simple')}
@@ -36,13 +37,19 @@ const Advance = (props: Props) => {
         <div className={styles.left}>
         <div className={styles.left}>
           <Editor
           <Editor
             mode="advance"
             mode="advance"
+            key={'advance'}
+            value={virtualRule.script}
             onValueChange={(v) => {
             onValueChange={(v) => {
               cacheRef.current = v;
               cacheRef.current = v;
+              setEditorValue(v);
               setSuccess(false);
               setSuccess(false);
             }}
             }}
           />
           />
           <Debug
           <Debug
-            virtualRule={virtualRule}
+            virtualRule={{
+              ...virtualRule,
+              script: editorValue,
+            }}
             onSuccess={() => {
             onSuccess={() => {
               setSuccess(true);
               setSuccess(true);
             }}
             }}

+ 1 - 0
src/components/FRuleEditor/Debug/index.tsx

@@ -160,6 +160,7 @@ const Debug = observer((props: Props) => {
     if (ws.current) {
     if (ws.current) {
       ws.current.unsubscribe();
       ws.current.unsubscribe();
     }
     }
+    console.log(props.virtualRule);
     if (!props.virtualRule.script) {
     if (!props.virtualRule.script) {
       setIsBeginning(true);
       setIsBeginning(true);
       message.warning('请编辑规则');
       message.warning('请编辑规则');

+ 44 - 26
src/components/FRuleEditor/Editor/index.tsx

@@ -1,8 +1,9 @@
 import styles from '@/components/FRuleEditor/index.less';
 import styles from '@/components/FRuleEditor/index.less';
 import { Dropdown, Menu, Tooltip } from 'antd';
 import { Dropdown, Menu, Tooltip } from 'antd';
 import { FullscreenOutlined, MoreOutlined } from '@ant-design/icons';
 import { FullscreenOutlined, MoreOutlined } from '@ant-design/icons';
-import MonacoEditor, { monaco } from 'react-monaco-editor';
-import { useEffect, useRef, useState } from 'react';
+import { monaco } from 'react-monaco-editor';
+import { JMonacoEditor } from '@/components/FMonacoEditor';
+import { useCallback, useEffect, useRef, useState } from 'react';
 import type * as monacoEditor from 'monaco-editor';
 import type * as monacoEditor from 'monaco-editor';
 import { Store } from 'jetlinks-store';
 import { Store } from 'jetlinks-store';
 import { State } from '@/components/FRuleEditor';
 import { State } from '@/components/FRuleEditor';
@@ -87,38 +88,52 @@ interface Props {
   onChange?: (value: 'advance' | 'simple') => void;
   onChange?: (value: 'advance' | 'simple') => void;
   id?: string;
   id?: string;
   onValueChange?: (v: any) => void;
   onValueChange?: (v: any) => void;
+  value?: string;
 }
 }
 
 
 const Editor = (props: Props) => {
 const Editor = (props: Props) => {
   const [loading, setLoading] = useState(false);
   const [loading, setLoading] = useState(false);
+  const [value, setValue] = useState<string | undefined>(State.code);
+
   const editorRef = useRef<monacoEditor.editor.IStandaloneCodeEditor>();
   const editorRef = useRef<monacoEditor.editor.IStandaloneCodeEditor>();
   const editorDidMountHandle = (editor: monacoEditor.editor.IStandaloneCodeEditor) => {
   const editorDidMountHandle = (editor: monacoEditor.editor.IStandaloneCodeEditor) => {
     editor.getAction('editor.action.formatDocument').run();
     editor.getAction('editor.action.formatDocument').run();
     editorRef.current = editor;
     editorRef.current = editor;
   };
   };
 
 
-  const handleInsertCode = (value: string) => {
-    const editor = editorRef.current;
-    if (!editor || !value) return;
-    const position = editor.getPosition()!;
-    editor?.executeEdits(State.code, [
-      {
-        range: new monaco.Range(
-          position?.lineNumber,
-          position?.column,
-          position?.lineNumber,
-          position?.column,
-        ),
-        text: value,
-      },
-    ]);
-    Store.set('add-operator-value', undefined);
-  };
+  useEffect(() => {
+    setValue(props.value);
+  }, [props.value]);
+
+  const handleInsertCode = useCallback(
+    (_value: string) => {
+      const editor = editorRef.current;
+      if (!editor || !_value) return;
+      const position = editor.getPosition()!;
+      editor?.executeEdits(value, [
+        {
+          range: new monaco.Range(
+            position?.lineNumber,
+            position?.column,
+            position?.lineNumber,
+            position?.column,
+          ),
+          text: _value,
+        },
+      ]);
+      // Store.set('add-operator-value', undefined);
+    },
+    [value],
+  );
 
 
   useEffect(() => {
   useEffect(() => {
-    const subscription = Store.subscribe('add-operator-value', handleInsertCode);
-    return () => subscription.unsubscribe();
+    let subscription: any = null;
+    if (props.mode === 'advance') {
+      subscription = Store.subscribe('add-operator-value', handleInsertCode);
+    }
+    return () => subscription?.unsubscribe();
   }, [props.mode]);
   }, [props.mode]);
+
   return (
   return (
     <div
     <div
       className={styles.box}
       className={styles.box}
@@ -185,16 +200,19 @@ const Editor = (props: Props) => {
         </div>
         </div>
       </div>
       </div>
       {loading && (
       {loading && (
-        <MonacoEditor
-          editorDidMount={(editor) => editorDidMountHandle(editor)}
+        <JMonacoEditor
+          editorDidMount={editorDidMountHandle}
           language={'javascript'}
           language={'javascript'}
           height={300}
           height={300}
           onChange={(c) => {
           onChange={(c) => {
-            State.code = c;
-            // Store.set('rule-editor-value', State.code);
+            setValue(c);
+            if (props.mode !== 'advance') {
+              State.code = c;
+              Store.set('rule-editor-value', State.code);
+            }
             props.onValueChange?.(c);
             props.onValueChange?.(c);
           }}
           }}
-          value={State.code}
+          value={value}
         />
         />
       )}
       )}
     </div>
     </div>

+ 2 - 1
src/components/FRuleEditor/Operator/index.tsx

@@ -77,9 +77,10 @@ const Operator = (props: Props) => {
             <div className={node.children?.length > 0 ? styles.parent : styles.add}>
             <div className={node.children?.length > 0 ? styles.parent : styles.add}>
               {node.type === 'property' ? (
               {node.type === 'property' ? (
                 <Popover
                 <Popover
-                  visible={visible}
+                  open={visible}
                   placement="right"
                   placement="right"
                   title="请选择使用值"
                   title="请选择使用值"
+                  onOpenChange={setVisible}
                   content={
                   content={
                     <Space direction="vertical">
                     <Space direction="vertical">
                       <Tooltip
                       <Tooltip

+ 12 - 8
src/components/FRuleEditor/index.tsx

@@ -42,19 +42,23 @@ const FRuleEditor = observer((props: Props) => {
   return (
   return (
     <>
     <>
       <Editor
       <Editor
+        key={'simple'}
         onChange={(v) => {
         onChange={(v) => {
           State.model = v;
           State.model = v;
         }}
         }}
+        value={value}
         id={props.id}
         id={props.id}
       />
       />
-      <Advance
-        model={State.model}
-        virtualRule={virtualRule}
-        id={props.id}
-        onChange={(v) => {
-          State.model = v;
-        }}
-      />
+      {State.model === 'advance' && (
+        <Advance
+          model={State.model}
+          virtualRule={virtualRule}
+          id={props.id}
+          onChange={(v) => {
+            State.model = v;
+          }}
+        />
+      )}
     </>
     </>
   );
   );
 });
 });

+ 1 - 1
src/components/ProTableCard/CardItems/Scene/index.tsx

@@ -235,7 +235,7 @@ const ContentRender = (data: SceneCardProps) => {
             <MyTooltip placement="topLeft" title={trigger?.when || ''}>
             <MyTooltip placement="topLeft" title={trigger?.when || ''}>
               <div
               <div
                 className={classNames(styles['card-item-content-trigger-item'], 'ellipsis')}
                 className={classNames(styles['card-item-content-trigger-item'], 'ellipsis')}
-                style={{ maxWidth: '15%' }}
+                style={{ maxWidth: '16%' }}
               >
               >
                 {trigger?.when || ''}
                 {trigger?.when || ''}
               </div>
               </div>

+ 0 - 9
src/pages/device/Instance/Detail/Functions/AdvancedMode.tsx

@@ -82,14 +82,6 @@ export default (props: FunctionProps) => {
     }
     }
   };
   };
 
 
-  const editorDidMountHandle = (editor: any) => {
-    monacoRef.current = editor;
-    editor.getAction('editor.action.formatDocument').run();
-    editor.onDidContentSizeChange?.(() => {
-      editor.getAction('editor.action.formatDocument').run();
-    });
-  };
-
   useEffect(() => {
   useEffect(() => {
     handleData(props.data);
     handleData(props.data);
   }, [props.data]);
   }, [props.data]);
@@ -107,7 +99,6 @@ export default (props: FunctionProps) => {
             onChange={(newValue: any) => {
             onChange={(newValue: any) => {
               setValue(newValue);
               setValue(newValue);
             }}
             }}
-            editorDidMount={editorDidMountHandle}
           />
           />
         </div>
         </div>
         <div className="button-tool">
         <div className="button-tool">

+ 1 - 1
src/pages/device/Instance/Detail/Functions/form.tsx

@@ -65,7 +65,7 @@ export default (props: FunctionProps) => {
       case 'object':
       case 'object':
         return <MetadataJsonInput json={record.json} />;
         return <MetadataJsonInput json={record.json} />;
       case 'password':
       case 'password':
-        return <Input type={'password'} />;
+        return <Input.Password />;
       case 'date':
       case 'date':
         return (
         return (
           // <>
           // <>

+ 2 - 2
src/pages/device/Instance/Detail/Parsing/index.tsx

@@ -2,7 +2,7 @@ import { useDomFullHeight } from '@/hooks';
 import { ExclamationCircleOutlined, ExpandOutlined } from '@ant-design/icons';
 import { ExclamationCircleOutlined, ExpandOutlined } from '@ant-design/icons';
 import { Card, Tooltip, Select, Input, Button, AutoComplete, message } from 'antd';
 import { Card, Tooltip, Select, Input, Button, AutoComplete, message } from 'antd';
 import { useState, useRef, useEffect } from 'react';
 import { useState, useRef, useEffect } from 'react';
-import MonacoEditor from 'react-monaco-editor';
+import { JMonacoEditor } from '@/components/FMonacoEditor';
 import { useFullscreen, useSize } from 'ahooks';
 import { useFullscreen, useSize } from 'ahooks';
 import Service from '@/pages/device/Instance/service';
 import Service from '@/pages/device/Instance/service';
 import { onlyMessage } from '@/utils/util';
 import { onlyMessage } from '@/utils/util';
@@ -244,7 +244,7 @@ const Parsing = (props: Props) => {
               }}
               }}
             ></div>
             ></div>
           )}
           )}
-          <MonacoEditor
+          <JMonacoEditor
             width={'100%'}
             width={'100%'}
             height={'100%'}
             height={'100%'}
             theme="vs"
             theme="vs"

+ 0 - 5
src/pages/device/components/Metadata/Import/index.tsx

@@ -233,11 +233,6 @@ const Import = (props: Props) => {
           height: 350,
           height: 350,
           theme: 'vs',
           theme: 'vs',
           language: 'json',
           language: 'json',
-          editorDidMount: (editor1: any) => {
-            editor1.onDidContentSizeChange?.(() => {
-              editor1.getAction('editor.action.formatDocument').run();
-            });
-          },
         },
         },
         'x-visible': false,
         'x-visible': false,
         'x-validator': [
         'x-validator': [

+ 48 - 2
src/pages/media/Device/Save/SaveProduct.tsx

@@ -1,7 +1,7 @@
 import { useEffect, useState } from 'react';
 import { useEffect, useState } from 'react';
 import { service } from '../index';
 import { service } from '../index';
 import { useRequest } from 'umi';
 import { useRequest } from 'umi';
-import { Form, Input, message, Modal } from 'antd';
+import { Form, Input, message, Modal, Select } from 'antd';
 import ProviderItem from './ProviderSelect';
 import ProviderItem from './ProviderSelect';
 
 
 interface SaveProps {
 interface SaveProps {
@@ -14,6 +14,7 @@ interface SaveProps {
 export default (props: SaveProps) => {
 export default (props: SaveProps) => {
   const { visible, close, reload } = props;
   const { visible, close, reload } = props;
   const [loading, setLoading] = useState(false);
   const [loading, setLoading] = useState(false);
+  const [extendFormItem, setExtendFormItem] = useState([]);
   const [form] = Form.useForm();
   const [form] = Form.useForm();
 
 
   const { data: providerList, run: getProviderList } = useRequest(service.queryProvider, {
   const { data: providerList, run: getProviderList } = useRequest(service.queryProvider, {
@@ -69,6 +70,17 @@ export default (props: SaveProps) => {
     }
     }
   };
   };
 
 
+  const handlerItem = (type: string, label: string, options: any[]) => {
+    switch (type) {
+      case 'enum':
+        return <Select placeholder={`请选择${label}`} options={options} />;
+      case 'password':
+        return <Input.Password placeholder={`请输入${label}`} />;
+      default:
+        return <Input placeholder={`请输入${label}`} />;
+    }
+  };
+
   return (
   return (
     <Modal
     <Modal
       maskClosable={false}
       maskClosable={false}
@@ -98,6 +110,23 @@ export default (props: SaveProps) => {
         >
         >
           <Input placeholder={'请输入产品名称'} />
           <Input placeholder={'请输入产品名称'} />
         </Form.Item>
         </Form.Item>
+        {extendFormItem.map((item: any) => {
+          let messageType = '请输入';
+          if (item.type === 'enum') {
+            messageType = '请选择';
+          }
+          return (
+            <Form.Item
+              name={item.name}
+              label={item.label}
+              required={item.required}
+              rules={[{ required: true, message: `${messageType}${item.label}` }]}
+              initialValue={item.value}
+            >
+              {handlerItem(item.type, item.label, item.options)}
+            </Form.Item>
+          );
+        })}
         <Form.Item
         <Form.Item
           name={'accessId'}
           name={'accessId'}
           label={'接入网关'}
           label={'接入网关'}
@@ -107,7 +136,7 @@ export default (props: SaveProps) => {
           <ProviderItem
           <ProviderItem
             options={providerList}
             options={providerList}
             type={props.type}
             type={props.type}
-            onSelect={(_, rowData) => {
+            onSelect={async (_, rowData) => {
               form.setFieldsValue({
               form.setFieldsValue({
                 accessName: rowData.name,
                 accessName: rowData.name,
                 protocolName: rowData.protocolDetail.name,
                 protocolName: rowData.protocolDetail.name,
@@ -115,6 +144,23 @@ export default (props: SaveProps) => {
                 transportProtocol: rowData.transportDetail.id,
                 transportProtocol: rowData.transportDetail.id,
                 accessProvider: rowData.provider,
                 accessProvider: rowData.provider,
               });
               });
+              service.getConfiguration(rowData.protocol, rowData.transport).then((res: any) => {
+                console.log(res);
+                const arr = res.result.properties.map((item: any) => {
+                  return {
+                    name: ['configuration', item.property],
+                    label: item.name,
+                    type: item.type?.type,
+                    value: item.type.expands?.defaultValue,
+                    options: item.type.elements?.map((e: any) => ({
+                      label: e.text,
+                      value: e.value,
+                    })),
+                    required: !!item.type.expands?.required,
+                  };
+                });
+                setExtendFormItem(arr);
+              });
             }}
             }}
           />
           />
         </Form.Item>
         </Form.Item>

+ 5 - 0
src/pages/media/Device/service.ts

@@ -42,6 +42,11 @@ class Service extends BaseService<DeviceItem> {
       method: 'GET',
       method: 'GET',
       params,
       params,
     });
     });
+
+  getConfiguration = (id: string, transport: string) =>
+    request(`/${SystemConst.API_BASE}/protocol/${id}/${transport}/configuration`, {
+      method: 'GET',
+    });
 }
 }
 
 
 export default Service;
 export default Service;

+ 3 - 14
src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/ObjModel.tsx

@@ -1,6 +1,6 @@
 import { Modal } from 'antd';
 import { Modal } from 'antd';
-import { useEffect, useRef, useState } from 'react';
-import MonacoEditor from 'react-monaco-editor';
+import { useEffect, useState } from 'react';
+import { JMonacoEditor } from '@/components/FMonacoEditor';
 
 
 interface Props {
 interface Props {
   value: any;
   value: any;
@@ -9,19 +9,9 @@ interface Props {
 }
 }
 
 
 export default (props: Props) => {
 export default (props: Props) => {
-  const monacoRef = useRef<any>();
-
   const [value, setValue] = useState<any>(props.value);
   const [value, setValue] = useState<any>(props.value);
   const [loading, setLoading] = useState(false);
   const [loading, setLoading] = useState(false);
 
 
-  const editorDidMountHandle = (editor: any) => {
-    monacoRef.current = editor;
-    editor.getAction('editor.action.formatDocument').run();
-    editor.onDidContentSizeChange?.(() => {
-      editor.getAction('editor.action.formatDocument').run();
-    });
-  };
-
   useEffect(() => {
   useEffect(() => {
     setValue(props?.value || '');
     setValue(props?.value || '');
   }, [props.value]);
   }, [props.value]);
@@ -46,7 +36,7 @@ export default (props: Props) => {
         }}
         }}
       >
       >
         {loading && (
         {loading && (
-          <MonacoEditor
+          <JMonacoEditor
             width={'100%'}
             width={'100%'}
             height={400}
             height={400}
             theme="vs-dark"
             theme="vs-dark"
@@ -55,7 +45,6 @@ export default (props: Props) => {
             onChange={(newValue) => {
             onChange={(newValue) => {
               setValue(newValue);
               setValue(newValue);
             }}
             }}
-            editorDidMount={editorDidMountHandle}
           />
           />
         )}
         )}
       </div>
       </div>

+ 29 - 1
src/pages/rule-engine/Scene/Save/action/ListItem/FilterCondition.tsx

@@ -4,7 +4,7 @@ import { CloseOutlined, PlusOutlined } from '@ant-design/icons';
 import { useEffect, useState, useCallback, useRef } from 'react';
 import { useEffect, useState, useCallback, useRef } from 'react';
 import classNames from 'classnames';
 import classNames from 'classnames';
 import { observer } from '@formily/react';
 import { observer } from '@formily/react';
-import { Popconfirm, Space } from 'antd';
+import { message, Popconfirm, Space } from 'antd';
 import './index.less';
 import './index.less';
 import { AIcon } from '@/components';
 import { AIcon } from '@/components';
 
 
@@ -49,6 +49,7 @@ export default observer((props: FilterProps) => {
   const [valueOptions] = useState<any[]>([]);
   const [valueOptions] = useState<any[]>([]);
   const [valueType, setValueType] = useState('');
   const [valueType, setValueType] = useState('');
   const labelCache = useRef<any[]>([undefined, undefined, {}, 'and']);
   const labelCache = useRef<any[]>([undefined, undefined, {}, 'and']);
+  const [paramsOpen, setParamsOpen] = useState(false);
 
 
   const [deleteVisible, setDeleteVisible] = useState(false);
   const [deleteVisible, setDeleteVisible] = useState(false);
   const columnsRef = useRef<string[]>([]);
   const columnsRef = useRef<string[]>([]);
@@ -259,6 +260,15 @@ export default observer((props: FilterProps) => {
               type="value"
               type="value"
               placeholder="参数值"
               placeholder="参数值"
               valueType={valueType}
               valueType={valueType}
+              open={paramsOpen}
+              openChange={(_open) => {
+                if (ValueRef.current.column) {
+                  setParamsOpen(_open);
+                } else {
+                  setParamsOpen(false);
+                  message.warning('请先选择参数');
+                }
+              }}
               value={value}
               value={value}
               BuiltInOptions={BuiltInOptions}
               BuiltInOptions={BuiltInOptions}
               showLabelKey="fullName"
               showLabelKey="fullName"
@@ -293,6 +303,15 @@ export default observer((props: FilterProps) => {
               type="value"
               type="value"
               placeholder="参数值"
               placeholder="参数值"
               valueType={valueType}
               valueType={valueType}
+              open={paramsOpen}
+              openChange={(_open) => {
+                if (ValueRef.current.column) {
+                  setParamsOpen(_open);
+                } else {
+                  setParamsOpen(false);
+                  message.warning('请先选择参数');
+                }
+              }}
               value={value}
               value={value}
               BuiltInOptions={BuiltInOptions}
               BuiltInOptions={BuiltInOptions}
               showLabelKey="fullName"
               showLabelKey="fullName"
@@ -329,6 +348,15 @@ export default observer((props: FilterProps) => {
             type="value"
             type="value"
             placeholder="参数值"
             placeholder="参数值"
             valueType={valueType}
             valueType={valueType}
+            open={paramsOpen}
+            openChange={(_open) => {
+              if (ValueRef.current.column) {
+                setParamsOpen(_open);
+              } else {
+                setParamsOpen(false);
+                message.warning('请先选择参数');
+              }
+            }}
             value={value}
             value={value}
             BuiltInOptions={BuiltInOptions}
             BuiltInOptions={BuiltInOptions}
             showLabelKey="fullName"
             showLabelKey="fullName"

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

@@ -22,6 +22,8 @@ export interface ParamsDropdownProps {
   valueType: string;
   valueType: string;
   showLabelKey?: string;
   showLabelKey?: string;
   icon?: ReactNode;
   icon?: ReactNode;
+  open?: boolean;
+  openChange?: (open: boolean) => void;
 }
 }
 
 
 interface MenusProps {
 interface MenusProps {
@@ -64,6 +66,10 @@ export default (props: ParamsDropdownProps) => {
   const [activeKey, setActiveKey] = useState(props.BuiltInOptions ? 'fixed' : 'manual');
   const [activeKey, setActiveKey] = useState(props.BuiltInOptions ? 'fixed' : 'manual');
   const [open, setOpen] = useState(false);
   const [open, setOpen] = useState(false);
 
 
+  useEffect(() => {
+    setOpen(!!props.open);
+  }, [props.open]);
+
   const onValueChange = useCallback(
   const onValueChange = useCallback(
     (value: any, _label: any, item?: any) => {
     (value: any, _label: any, item?: any) => {
       setMyValue(value);
       setMyValue(value);
@@ -99,6 +105,18 @@ export default (props: ParamsDropdownProps) => {
               placeholder={'请输入'}
               placeholder={'请输入'}
             />
             />
           );
           );
+        case 'metric':
+          return (
+            <Menus
+              value={_value}
+              options={props.metricsOptions}
+              onChange={(v, l) => {
+                console.log(l);
+                onValueChange(v, l);
+                setOpen(false);
+              }}
+            />
+          );
         case 'enum':
         case 'enum':
           return (
           return (
             <Menus
             <Menus
@@ -173,11 +191,14 @@ export default (props: ParamsDropdownProps) => {
     [props, activeKey],
     [props, activeKey],
   );
   );
 
 
-  const findLabel = (value: string, data: any[]): boolean => {
+  const findLabel = (value: string, data: any[], titleName?: string): boolean => {
     let isLabel = false;
     let isLabel = false;
     return data.some((item) => {
     return data.some((item) => {
       if (item.key === value) {
       if (item.key === value) {
         let titleKey = 'title';
         let titleKey = 'title';
+        if (titleName) {
+          titleKey = titleName;
+        }
         if (props.showLabelKey) {
         if (props.showLabelKey) {
           titleKey = props.showLabelKey;
           titleKey = props.showLabelKey;
         }
         }
@@ -196,6 +217,9 @@ export default (props: ParamsDropdownProps) => {
         case 'boolean':
         case 'boolean':
           setLabel(v ? '是' : '否');
           setLabel(v ? '是' : '否');
           break;
           break;
+        case 'metric':
+          findLabel(v, props.metricsOptions || []);
+          break;
         case 'enum':
         case 'enum':
         case 'object':
         case 'object':
           findLabel(v, props.options || []);
           findLabel(v, props.options || []);
@@ -274,7 +298,7 @@ export default (props: ParamsDropdownProps) => {
       _itemList.push({
       _itemList.push({
         key: 'metric',
         key: 'metric',
         label: '指标值',
         label: '指标值',
-        content: renderNode('enum', myValue, props),
+        content: renderNode('metric', myValue, props),
       });
       });
     }
     }
   }
   }
@@ -299,7 +323,10 @@ export default (props: ParamsDropdownProps) => {
       bodyStyle={{ width: 'auto' }}
       bodyStyle={{ width: 'auto' }}
       type={props.valueType}
       type={props.valueType}
       open={open}
       open={open}
-      openChange={setOpen}
+      openChange={(_open) => {
+        setOpen(_open);
+        props.openChange?.(_open);
+      }}
     >
     >
       <div
       <div
         className={classNames(styles['dropdown-button'], styles.value)}
         className={classNames(styles['dropdown-button'], styles.value)}

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

@@ -29,6 +29,12 @@ export default observer((props: Props) => {
   const [visible, setVisible] = useState(false);
   const [visible, setVisible] = useState(false);
 
 
   useEffect(() => {
   useEffect(() => {
+    return () => {
+      set(FormModel.current, ['options', 'trigger'], {});
+    };
+  }, []);
+
+  useEffect(() => {
     if (FormModel.current.trigger!.device?.productId) {
     if (FormModel.current.trigger!.device?.productId) {
       service.detail(FormModel.current.trigger!.device?.productId).then((res) => {
       service.detail(FormModel.current.trigger!.device?.productId).then((res) => {
         if (res.status === 200) {
         if (res.status === 200) {

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

@@ -154,14 +154,18 @@ const ParamsItem = observer((props: ParamsItemProps) => {
           if (labelOptions.metrics) {
           if (labelOptions.metrics) {
             // 指标值
             // 指标值
             const _metrics = labelOptions.metrics.map((mItem: any) => ({
             const _metrics = labelOptions.metrics.map((mItem: any) => ({
-              title: mItem.name,
-              key: mItem.id,
+              ...mItem,
+              label: mItem.name,
+              value: mItem.value,
             }));
             }));
             setMetricsOptions(_metrics);
             setMetricsOptions(_metrics);
+          } else {
+            setMetricsOptions([]);
           }
           }
         } else {
         } else {
           props.onChange?.({});
           props.onChange?.({});
           setTtOptions([]);
           setTtOptions([]);
+          setMetricsOptions([]);
           setValueType('');
           setValueType('');
         }
         }
       }
       }
@@ -293,7 +297,14 @@ const ParamsItem = observer((props: ParamsItemProps) => {
           <>
           <>
             <ParamsDropdown
             <ParamsDropdown
               options={valueOptions}
               options={valueOptions}
-              metricsOptions={metricsOptions}
+              metricsOptions={metricsOptions.filter((mItem) => {
+                if (ValueRef.current.termType && DoubleFilter.includes(ValueRef.current.termType)) {
+                  return mItem.range;
+                } else {
+                  return !mItem.range;
+                }
+              })}
+              isMetric={!!metricsOptions.length}
               type="value"
               type="value"
               placeholder="参数值"
               placeholder="参数值"
               valueType={valueType}
               valueType={valueType}
@@ -315,7 +326,14 @@ const ParamsItem = observer((props: ParamsItemProps) => {
             />
             />
             <ParamsDropdown
             <ParamsDropdown
               options={valueOptions}
               options={valueOptions}
-              metricsOptions={metricsOptions}
+              metricsOptions={metricsOptions.filter((mItem) => {
+                if (ValueRef.current.termType && DoubleFilter.includes(ValueRef.current.termType)) {
+                  return mItem.range;
+                } else {
+                  return !mItem.range;
+                }
+              })}
+              isMetric={!!metricsOptions.length}
               type="value"
               type="value"
               placeholder="参数值"
               placeholder="参数值"
               valueType={valueType}
               valueType={valueType}
@@ -339,7 +357,15 @@ const ParamsItem = observer((props: ParamsItemProps) => {
         ) : (
         ) : (
           <ParamsDropdown
           <ParamsDropdown
             options={valueOptions}
             options={valueOptions}
-            metricsOptions={metricsOptions}
+            metricsOptions={metricsOptions.filter((mItem) => {
+              console.log(mItem);
+              if (ValueRef.current.termType && DoubleFilter.includes(ValueRef.current.termType)) {
+                return mItem.range;
+              } else {
+                return !mItem.range;
+              }
+            })}
+            isMetric={!!metricsOptions.length}
             type="value"
             type="value"
             placeholder="参数值"
             placeholder="参数值"
             valueType={valueType}
             valueType={valueType}

+ 6 - 7
src/pages/system/Apply/Api/swagger-ui/debugging.tsx

@@ -1,7 +1,7 @@
 import { TitleComponent } from '@/components';
 import { TitleComponent } from '@/components';
 import ReactJson from 'react-json-view';
 import ReactJson from 'react-json-view';
 import { request } from 'umi';
 import { request } from 'umi';
-import MonacoEditor from 'react-monaco-editor';
+import { JMonacoEditor } from '@/components/FMonacoEditor';
 import { Button, Input } from 'antd';
 import { Button, Input } from 'antd';
 import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
 import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
 import { createSchemaField, FormProvider, observer } from '@formily/react';
 import { createSchemaField, FormProvider, observer } from '@formily/react';
@@ -20,13 +20,12 @@ export default observer(() => {
 
 
   useEffect(() => {
   useEffect(() => {
     if (ApiModel.debugger.body && editor.current) {
     if (ApiModel.debugger.body && editor.current) {
-      const { editor: MEditor } = editor.current;
-      MEditor.setValue(JSON.stringify(ApiModel.debugger.body));
+      editor.current.setValue(JSON.stringify(ApiModel.debugger.body));
       setTimeout(() => {
       setTimeout(() => {
-        MEditor.getAction('editor.action.formatDocument').run();
+        editor.current.getAction('editor.action.formatDocument').run();
       }, 300);
       }, 300);
       // MEditor.trigger('anyString', 'editor.action.formatDocument');//自动格式化代码
       // MEditor.trigger('anyString', 'editor.action.formatDocument');//自动格式化代码
-      MEditor.setValue(MEditor.getValue());
+      editor.current.setValue(editor.current.getValue());
     }
     }
   }, [ApiModel.debugger, editor.current]);
   }, [ApiModel.debugger, editor.current]);
 
 
@@ -215,11 +214,10 @@ export default observer(() => {
             </FormProvider>
             </FormProvider>
           )}
           )}
           {ApiModel.debugger.body && (
           {ApiModel.debugger.body && (
-            <MonacoEditor
+            <JMonacoEditor
               height={200}
               height={200}
               language={'json'}
               language={'json'}
               theme={'dark'}
               theme={'dark'}
-              ref={editor}
               onChange={(value) => {
               onChange={(value) => {
                 try {
                 try {
                   setBody(JSON.parse(value));
                   setBody(JSON.parse(value));
@@ -228,6 +226,7 @@ export default observer(() => {
                 }
                 }
               }}
               }}
               editorDidMount={(_editor) => {
               editorDidMount={(_editor) => {
+                editor.current = _editor;
                 _editor.getAction('editor.action.formatDocument').run();
                 _editor.getAction('editor.action.formatDocument').run();
               }}
               }}
             />
             />

+ 4 - 4
src/pages/system/Apply/Home/index.tsx

@@ -1,5 +1,5 @@
 import { Table } from 'antd';
 import { Table } from 'antd';
-import MonacoEditor from 'react-monaco-editor';
+import { JMonacoEditor } from '@/components/FMonacoEditor';
 import './index.less';
 import './index.less';
 const Home = () => {
 const Home = () => {
   const data = [
   const data = [
@@ -126,7 +126,7 @@ const Home = () => {
           <div>
           <div>
             <p>使用和签名相同的算法(不需要对响应结果排序)</p>
             <p>使用和签名相同的算法(不需要对响应结果排序)</p>
             <div>
             <div>
-              <MonacoEditor
+              <JMonacoEditor
                 width={'100%'}
                 width={'100%'}
                 height={620}
                 height={620}
                 theme="vs-dark"
                 theme="vs-dark"
@@ -147,7 +147,7 @@ const Home = () => {
         <h3>添加 SDK 依赖</h3>
         <h3>添加 SDK 依赖</h3>
         <div className="h3-text">将以下Maven依赖加入到pom.xml文件中</div>
         <div className="h3-text">将以下Maven依赖加入到pom.xml文件中</div>
         <div>
         <div>
-          <MonacoEditor
+          <JMonacoEditor
             width={'100%'}
             width={'100%'}
             height={100}
             height={100}
             theme="vs-dark"
             theme="vs-dark"
@@ -159,7 +159,7 @@ const Home = () => {
         </div>
         </div>
         <h3>SDK 客户端的初始化和请求方式</h3>
         <h3>SDK 客户端的初始化和请求方式</h3>
         <div>
         <div>
-          <MonacoEditor
+          <JMonacoEditor
             width={'100%'}
             width={'100%'}
             height={370}
             height={370}
             theme="vs-dark"
             theme="vs-dark"

+ 6 - 7
src/pages/system/Platforms/Api/swagger-ui/debugging.tsx

@@ -1,7 +1,7 @@
 import { TitleComponent } from '@/components';
 import { TitleComponent } from '@/components';
 import ReactJson from 'react-json-view';
 import ReactJson from 'react-json-view';
 import { request } from 'umi';
 import { request } from 'umi';
-import MonacoEditor from 'react-monaco-editor';
+import { JMonacoEditor } from '@/components/FMonacoEditor';
 import { Button, Input, Popconfirm } from 'antd';
 import { Button, Input, Popconfirm } from 'antd';
 import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
 import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
 import { createSchemaField, FormProvider, observer } from '@formily/react';
 import { createSchemaField, FormProvider, observer } from '@formily/react';
@@ -50,13 +50,12 @@ export default observer(() => {
   useEffect(() => {
   useEffect(() => {
     console.log('ApiModel.debugger.body', ApiModel.debugger.body);
     console.log('ApiModel.debugger.body', ApiModel.debugger.body);
     if (ApiModel.debugger.body && editor.current) {
     if (ApiModel.debugger.body && editor.current) {
-      const { editor: MEditor } = editor.current;
-      MEditor.setValue(JSON.stringify(ApiModel.debugger.body));
+      editor.current.setValue(JSON.stringify(ApiModel.debugger.body));
       setTimeout(() => {
       setTimeout(() => {
-        MEditor.getAction('editor.action.formatDocument').run();
+        editor.current.getAction('editor.action.formatDocument').run();
       }, 300);
       }, 300);
       // MEditor.trigger('anyString', 'editor.action.formatDocument');//自动格式化代码
       // MEditor.trigger('anyString', 'editor.action.formatDocument');//自动格式化代码
-      MEditor.setValue(MEditor.getValue());
+      editor.current.setValue(editor.current.getValue());
     }
     }
   }, [ApiModel.debugger, editor.current]);
   }, [ApiModel.debugger, editor.current]);
 
 
@@ -248,11 +247,10 @@ export default observer(() => {
             </FormProvider>
             </FormProvider>
           )}
           )}
           {isBody() && (
           {isBody() && (
-            <MonacoEditor
+            <JMonacoEditor
               height={200}
               height={200}
               language={'json'}
               language={'json'}
               theme={'dark'}
               theme={'dark'}
-              ref={editor}
               onChange={(value) => {
               onChange={(value) => {
                 try {
                 try {
                   setBody(JSON.parse(value));
                   setBody(JSON.parse(value));
@@ -261,6 +259,7 @@ export default observer(() => {
                 }
                 }
               }}
               }}
               editorDidMount={(_editor) => {
               editorDidMount={(_editor) => {
+                editor.current = _editor;
                 _editor.getAction('editor.action.formatDocument').run();
                 _editor.getAction('editor.action.formatDocument').run();
               }}
               }}
             />
             />

+ 4 - 4
src/pages/system/Platforms/Home/index.tsx

@@ -1,5 +1,5 @@
 import { Table } from 'antd';
 import { Table } from 'antd';
-import MonacoEditor from 'react-monaco-editor';
+import { JMonacoEditor } from '@/components/FMonacoEditor';
 import './index.less';
 import './index.less';
 const Home = () => {
 const Home = () => {
   const data = [
   const data = [
@@ -126,7 +126,7 @@ const Home = () => {
           <div>
           <div>
             <p>使用和签名相同的算法(不需要对响应结果排序)</p>
             <p>使用和签名相同的算法(不需要对响应结果排序)</p>
             <div>
             <div>
-              <MonacoEditor
+              <JMonacoEditor
                 width={'100%'}
                 width={'100%'}
                 height={620}
                 height={620}
                 theme="vs-dark"
                 theme="vs-dark"
@@ -147,7 +147,7 @@ const Home = () => {
         <h3>添加 SDK 依赖</h3>
         <h3>添加 SDK 依赖</h3>
         <div className="h3-text">将以下Maven依赖加入到pom.xml文件中</div>
         <div className="h3-text">将以下Maven依赖加入到pom.xml文件中</div>
         <div>
         <div>
-          <MonacoEditor
+          <JMonacoEditor
             width={'100%'}
             width={'100%'}
             height={100}
             height={100}
             theme="vs-dark"
             theme="vs-dark"
@@ -159,7 +159,7 @@ const Home = () => {
         </div>
         </div>
         <h3>SDK 客户端的初始化和请求方式</h3>
         <h3>SDK 客户端的初始化和请求方式</h3>
         <div>
         <div>
-          <MonacoEditor
+          <JMonacoEditor
             width={'100%'}
             width={'100%'}
             height={370}
             height={370}
             theme="vs-dark"
             theme="vs-dark"