Kaynağa Gözat

feat: 优化功能调试

xieyonghong 3 yıl önce
ebeveyn
işleme
9e8591b43a

+ 1 - 1
src/components/AMapComponent/APILoader.ts

@@ -19,7 +19,7 @@ export const getAMapPlugins = (type: string, map: any, callback: Function) => {
   }
 };
 
-export const getAMapUiPromise = (version: string = '1.1'): Promise<any> => {
+export const getAMapUiPromise = (version: string = '1.0'): Promise<any> => {
   if ((window as any).AMapUI) {
     return Promise.resolve();
   }

+ 4 - 3
src/components/AMapComponent/amap.tsx

@@ -12,7 +12,7 @@ interface AMapProps extends Omit<MapProps, 'amapkey' | 'useAMapUI'> {
 }
 
 export default (props: AMapProps) => {
-  const { style, className, events, onInstanceCreated, ...extraProps } = props;
+  const { style, className, events, onInstanceCreated, children, ...extraProps } = props;
 
   const [uiLoading, setUiLoading] = useState(false);
 
@@ -36,12 +36,13 @@ export default (props: AMapProps) => {
     }
   };
 
+  console.log(isOpenUi, uiLoading);
+
   return (
     <div style={style || { width: '100%', height: '100%' }} className={className}>
       {amapKey ? (
         // @ts-ignore
         <Map
-          version={'2.0'}
           amapkey={amapKey}
           zooms={[3, 20]}
           events={
@@ -56,7 +57,7 @@ export default (props: AMapProps) => {
           }
           {...extraProps}
         >
-          {isOpenUi ? (uiLoading ? props.children : null) : props.children}
+          {isOpenUi ? (uiLoading ? children : null) : children}
         </Map>
       ) : (
         <Empty description={'请配置高德地图key'} />

+ 117 - 0
src/components/FormItems/MetadataJsonInput/index.tsx

@@ -0,0 +1,117 @@
+import { Input, Modal } from 'antd';
+import { EnvironmentOutlined } from '@ant-design/icons';
+import { useEffect, useState } from 'react';
+import MonacoEditor from 'react-monaco-editor';
+import { isObject } from 'lodash';
+
+type MetaDataJsonInputProps = {
+  json: Record<string, any>;
+  value?: string;
+  onChange?: (value: string) => void;
+};
+
+export const MetaDataJsonHandle = (data: any): Record<string, any> => {
+  const _JSON = {};
+
+  if (isObject(data)) {
+    const type = (data as any).valueType.type;
+    const id = (data as any).id;
+
+    switch (type) {
+      case 'object':
+        _JSON[id] = MetaDataJsonHandle((data as any)['json']['properties'][0]);
+        break;
+      case 'array':
+        _JSON[id] = [];
+        break;
+      case 'int':
+      case 'long':
+      case 'float':
+      case 'double':
+        _JSON[id] = 0;
+        break;
+      case 'boolean':
+        _JSON[id] = false;
+        break;
+      default:
+        _JSON[id] = '';
+        break;
+    }
+  }
+
+  return _JSON;
+};
+
+export default (props: MetaDataJsonInputProps) => {
+  const [value, setValue] = useState(props.value || '');
+  const [visible, setVisible] = useState(false);
+  const [monacoValue, setMonacoValue] = useState<string>('');
+
+  const onChange = (data: string) => {
+    if (props.onChange) {
+      const newData = data.replace(/[ ]/g, '');
+      props.onChange(newData);
+    }
+  };
+
+  const editorDidMountHandle = (editor: any) => {
+    editor.onDidContentSizeChange?.(() => {
+      editor.getAction('editor.action.formatDocument').run();
+    });
+  };
+
+  useEffect(() => {
+    setValue(props.value || '');
+  }, [props.value]);
+
+  useEffect(() => {
+    if (props.json) {
+      const _json = MetaDataJsonHandle(props.json);
+      onChange(JSON.stringify(_json));
+    }
+  }, [props.json]);
+
+  return (
+    <>
+      <Input
+        addonAfter={
+          <EnvironmentOutlined
+            onClick={() => {
+              setMonacoValue(value);
+              setVisible(true);
+            }}
+          />
+        }
+        value={value}
+        onChange={(e) => {
+          setValue(e.target.value);
+          onChange(e.target.value);
+        }}
+      />
+      <Modal
+        visible={visible}
+        title={'编辑'}
+        onOk={() => {
+          onChange(monacoValue);
+          setVisible(false);
+        }}
+        onCancel={() => {
+          setVisible(false);
+        }}
+        width={700}
+      >
+        <MonacoEditor
+          width={'100%'}
+          height={400}
+          theme="vs-dark"
+          language={'json'}
+          value={monacoValue}
+          onChange={(newValue) => {
+            setMonacoValue(newValue);
+          }}
+          editorDidMount={editorDidMountHandle}
+        />
+      </Modal>
+    </>
+  );
+};

+ 97 - 0
src/components/GeoPoint/AMap.tsx

@@ -0,0 +1,97 @@
+import { AMap } from '@/components';
+import usePlaceSearch from '@/components/AMapComponent/hooks/PlaceSearch';
+import { Input, Modal, Select } from 'antd';
+import { debounce } from 'lodash';
+import { Marker } from 'react-amap';
+import { useEffect, useState } from 'react';
+import './style';
+
+interface Props {
+  value: any;
+  close: () => void;
+  ok: (data: any) => void;
+}
+
+type MarkerPointType = {
+  longitude: number;
+  latitude: number;
+};
+
+export default (props: Props) => {
+  const [markerCenter, setMarkerCenter] = useState<MarkerPointType>({ longitude: 0, latitude: 0 });
+  const [map, setMap] = useState<any>(null);
+
+  const { data, search } = usePlaceSearch(map);
+
+  const [value, setValue] = useState<any>(props.value);
+
+  const onSearch = (value1: string) => {
+    search(value1);
+  };
+
+  useEffect(() => {
+    setValue(props?.value || '');
+    const list = (props?.value || '').split(',') || [];
+    if (!!props.value && list.length === 2) {
+      setMarkerCenter({
+        longitude: list[0],
+        latitude: list[1],
+      });
+    }
+  }, [props.value]);
+  console.log(markerCenter);
+
+  return (
+    <Modal
+      visible
+      title="地理位置"
+      width={'55vw'}
+      onCancel={() => props.close()}
+      onOk={() => {
+        props.ok(value);
+      }}
+    >
+      <div className={'map-search-warp'}>
+        <div className={'map-search-select'}>
+          <Select
+            showSearch
+            options={data}
+            filterOption={false}
+            onSearch={debounce(onSearch, 300)}
+            style={{ width: '100%', marginBottom: 10 }}
+            onSelect={(key: string, node: any) => {
+              setValue(key);
+              setMarkerCenter({
+                longitude: node.lnglat.lng,
+                latitude: node.lnglat.lat,
+              });
+            }}
+          />
+          <Input value={value} readOnly />
+        </div>
+        <AMap
+          style={{
+            height: 500,
+            width: '100%',
+          }}
+          center={markerCenter.longitude ? markerCenter : undefined}
+          onInstanceCreated={setMap}
+          events={{
+            click: (e: any) => {
+              setValue(`${e.lnglat.lng},${e.lnglat.lat}`);
+              setMarkerCenter({
+                longitude: e.lnglat.lng,
+                latitude: e.lnglat.lat,
+              });
+            },
+          }}
+        >
+          {markerCenter.longitude ? (
+            // @ts-ignore
+            <Marker kye={'marker'} position={markerCenter} />
+          ) : null}
+        </AMap>
+      </div>
+    </Modal>
+  );
+};

+ 13 - 0
src/components/GeoPoint/index.less

@@ -0,0 +1,13 @@
+.map-search-warp {
+  position: relative;
+
+  .map-search-select {
+    position: absolute;
+    top: 5px;
+    right: 5px;
+    z-index: 9;
+    width: 300px;
+    padding: 10px;
+    background-color: #fff;
+  }
+}

+ 55 - 0
src/components/GeoPoint/index.tsx

@@ -0,0 +1,55 @@
+import { EnvironmentOutlined } from '@ant-design/icons';
+import { Input } from 'antd';
+import { useEffect, useState } from 'react';
+import AMap from './AMap';
+
+interface Props {
+  value?: string;
+  onChange?: (value: string) => void;
+}
+
+const GeoComponent = (props: Props) => {
+  const [visible, setVisible] = useState<boolean>(false);
+  const [value, setValue] = useState<any>(props?.value);
+
+  useEffect(() => {
+    setValue(props?.value);
+  }, [props.value]);
+
+  return (
+    <div>
+      <Input
+        addonAfter={
+          <EnvironmentOutlined
+            onClick={() => {
+              setVisible(true);
+            }}
+          />
+        }
+        value={value}
+        onChange={(e) => {
+          // setValue(e.target.value);
+          if (props.onChange) {
+            props.onChange(e.target.value);
+          }
+        }}
+      />
+      {visible && (
+        <AMap
+          value={value}
+          close={() => {
+            setVisible(false);
+          }}
+          ok={(param) => {
+            if (props.onChange) {
+              props.onChange(param);
+            }
+            // setValue(param);
+            setVisible(false);
+          }}
+        />
+      )}
+    </div>
+  );
+};
+export default GeoComponent;

+ 1 - 0
src/components/GeoPoint/style.js

@@ -0,0 +1 @@
+import './index.less';

+ 2 - 0
src/components/index.ts

@@ -12,3 +12,5 @@ export { default as TitleComponent } from './TitleComponent';
 export { default as AMap } from './AMapComponent/amap';
 export { default as PathSimplifier } from './AMapComponent/PathSimplifier';
 export { default as Empty } from './Empty';
+export { default as GeoPoint } from './GeoPoint';
+export { default as MetadataJsonInput } from './FormItems/MetadataJsonInput';

+ 28 - 2
src/pages/device/Instance/Detail/Functions/AdvancedMode.tsx

@@ -7,6 +7,7 @@ import MonacoEditor from 'react-monaco-editor';
 import { isObject } from 'lodash';
 
 import './index.less';
+import { MetaDataJsonHandle } from '@/components/FormItems/MetadataJsonInput';
 
 type FunctionProps = {
   data: FunctionMetadata;
@@ -44,9 +45,31 @@ export default (props: FunctionProps) => {
 
   const handleData = (data: any) => {
     const obj = {};
-    const properties = data.valueType ? data.valueType.properties : [];
+
+    const properties = data.valueType ? data.valueType.properties : data.inputs;
+
     for (const datum of properties) {
-      obj[datum.id] = '';
+      switch (datum.valueType.type) {
+        case 'object':
+          obj[datum.id] = MetaDataJsonHandle(datum['json']['properties'][0]);
+          break;
+        case 'array':
+          obj[datum.id] = [];
+          break;
+        case 'int':
+        case 'long':
+        case 'float':
+        case 'double':
+          obj[datum.id] = 0;
+          break;
+        case 'boolean':
+          obj[datum.id] = false;
+          break;
+        default:
+          obj[datum.id] = '';
+          break;
+      }
+      // obj[datum.id] = '';
     }
     setValue(JSON.stringify(obj));
 
@@ -57,6 +80,9 @@ export default (props: FunctionProps) => {
 
   const editorDidMountHandle = (editor: any) => {
     monacoRef.current = editor;
+    editor.onDidContentSizeChange?.(() => {
+      editor.getAction('editor.action.formatDocument').run();
+    });
   };
 
   useEffect(() => {

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

@@ -9,6 +9,7 @@ import ProForm from '@ant-design/pro-form';
 import { InstanceModel, service } from '@/pages/device/Instance';
 import moment from 'moment';
 import './index.less';
+import { GeoPoint, MetadataJsonInput } from '@/components';
 
 type FunctionProps = {
   data: FunctionMetadata;
@@ -57,6 +58,10 @@ export default (props: FunctionProps) => {
       case 'float':
       case 'double':
         return <InputNumber style={{ width: '100%' }} placeholder={'请输入' + name} />;
+      case 'geoPoint':
+        return <GeoPoint />;
+      case 'object':
+        return <MetadataJsonInput json={record.json} />;
       case 'date':
         return (
           <>
@@ -106,12 +111,16 @@ export default (props: FunctionProps) => {
     const properties = data.valueType ? data.valueType.properties : data.inputs;
 
     for (const datum of properties) {
+      console.log(datum);
+      const type = datum.valueType ? datum.valueType.type : '-';
+
       array.push({
         id: datum.id,
         name: datum.name,
-        type: datum.valueType ? datum.valueType.type : '-',
+        type: type,
         format: datum.valueType ? datum.valueType.format : undefined,
         options: datum.valueType ? datum.valueType.elements : undefined,
+        json: type === 'object' ? datum['json']['properties'][0] : undefined,
         value: undefined,
       });
     }
@@ -134,6 +143,8 @@ export default (props: FunctionProps) => {
         if (d.value) {
           if (d.type === 'date') {
             data[d.id] = moment(d.value).format('YYYY-MM-DD HH:mm:ss');
+          } else if (d.type === 'object') {
+            data[d.id] = JSON.parse(d.value);
           } else {
             data[d.id] = d.value;
           }