Преглед изворни кода

feat(metadata): cat product metadata

Lind пре 4 година
родитељ
комит
1f156df3fc

+ 1 - 1
src/app.tsx

@@ -53,7 +53,7 @@ export async function getInitialState(): Promise<{
 
   const ws = new ReconnectingWebSocket(url);
 
-  ws.send('sss');
+  // ws.send('sss');
   ws.onerror = () => {
     console.log('链接错误。ws');
   };

+ 64 - 0
src/pages/device/Product/Detail/Metadata/Cat/index.tsx

@@ -0,0 +1,64 @@
+import { Drawer, Tabs } from 'antd';
+import { useEffect, useState } from 'react';
+import { productModel, service } from '@/pages/device/Product';
+import MonacoEditor from 'react-monaco-editor';
+
+interface Props {
+  visible: boolean;
+  close: () => void;
+}
+
+const Cat = (props: Props) => {
+  const [codecs, setCodecs] = useState<{ id: string; name: string }[]>();
+  const metadata = productModel.current?.metadata as string;
+  const [value, setValue] = useState(metadata);
+  useEffect(() => {
+    service.codecs().subscribe({
+      next: (data) => {
+        setCodecs([{ id: 'jetlinks', name: 'jetlinks' }].concat(data));
+      },
+    });
+  }, []);
+
+  const convertMetadata = (key: string) => {
+    if (key === 'alink') {
+      service.convertMetadata('to', 'alink', JSON.parse(metadata)).subscribe({
+        next: (data) => {
+          setValue(JSON.stringify(data));
+        },
+      });
+    } else {
+      setValue(metadata);
+    }
+  };
+  return (
+    <Drawer title="查看物模型" onClose={() => props.close()} visible={props.visible}>
+      <div style={{ background: 'rgb(236, 237, 238)' }}>
+        <p style={{ padding: 10 }}>
+          物模型是对设备在云端的功能描述,包括设备的属性、服务和事件。物联网平台通过定义一种物的描述语言来描述物模型,称之为
+          TSL(即 Thing Specification Language),采用 JSON 格式,您可以根据 TSL
+          组装上报设备的数据。您可以导出完整物模型,用于云端应用开发。
+        </p>
+      </div>
+      <Tabs onChange={convertMetadata}>
+        {codecs?.map((item) => (
+          <Tabs.TabPane tab={item.name} tabKey={item.id} key={item.id}>
+            <MonacoEditor
+              height={350}
+              theme="vs"
+              language="json"
+              value={value}
+              editorDidMount={(editor) => {
+                editor.onDidScrollChange?.(() => {
+                  editor.getAction('editor.action.formatDocument').run();
+                });
+              }}
+            />
+          </Tabs.TabPane>
+        ))}
+      </Tabs>
+    </Drawer>
+  );
+};
+
+export default Cat;

+ 41 - 22
src/pages/device/Product/Detail/Metadata/Import/index.tsx

@@ -72,6 +72,36 @@ const Import = (props: Props) => {
         ],
       },
       metadata: {
+        title: '物模型类型',
+        'x-decorator': 'FormItem',
+        'x-component': 'Select',
+        'x-decorator-props': {
+          width: '800px',
+        },
+        'x-component-props': {
+          width: '800px',
+        },
+        default: 'jetlinks',
+        'x-reactions': {
+          dependencies: ['.type'],
+          fulfill: {
+            state: {
+              visible: "{{$deps[0]==='import'}}",
+            },
+          },
+        },
+        enum: [
+          {
+            label: 'Jetlinks物模型',
+            value: 'jetlinks',
+          },
+          {
+            label: '阿里云物模型TSL',
+            value: 'alink',
+          },
+        ],
+      },
+      layout: {
         type: 'void',
         'x-component': 'Space',
         'x-visible': false,
@@ -83,6 +113,7 @@ const Import = (props: Props) => {
             },
           },
         },
+
         properties: {
           upload: {
             'x-decorator': 'FormItem',
@@ -104,27 +135,6 @@ const Import = (props: Props) => {
               },
             },
           },
-          metadata: {
-            'x-decorator': 'FormItem',
-            'x-component': 'Select',
-            'x-decorator-props': {
-              width: '800px',
-            },
-            'x-component-props': {
-              width: '800px',
-            },
-            default: 'jetlinks',
-            enum: [
-              {
-                label: 'Jetlinks物模型',
-                value: 'jetlinks',
-              },
-              {
-                label: '阿里云物模型TSL',
-                value: 'alink',
-              },
-            ],
-          },
         },
       },
       import: {
@@ -156,7 +166,16 @@ const Import = (props: Props) => {
 
   const handleImport = async () => {
     const data = (await form.submit()) as any;
-    await service.modify(param.id, { metadata: data[data.type] });
+
+    if (data.metadata === 'alink') {
+      service.convertMetadata('from', 'alink', data.import).subscribe({
+        next: async (meta) => {
+          await service.modify(param.id, { metadata: JSON.stringify(meta) });
+        },
+      });
+    } else {
+      await service.modify(param.id, { metadata: data[data.type] });
+    }
     message.success('导入成功');
   };
   return (

+ 4 - 1
src/pages/device/Product/Detail/Metadata/index.tsx

@@ -4,10 +4,12 @@ import BaseMetadata from '@/pages/device/Product/Detail/Metadata/Base';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import Import from '@/pages/device/Product/Detail/Metadata/Import';
 import { useState } from 'react';
+import Cat from '@/pages/device/Product/Detail/Metadata/Cat';
 
 const Metadata = observer(() => {
   const intl = useIntl();
   const [visible, setVisible] = useState<boolean>(false);
+  const [cat, setCat] = useState<boolean>(false);
   return (
     <>
       <Tabs
@@ -19,7 +21,7 @@ const Metadata = observer(() => {
                 defaultMessage: '快速导入',
               })}
             </Button>
-            <Button>
+            <Button onClick={() => setCat(true)}>
               {intl.formatMessage({
                 id: 'pages.device.productDetail.metadata',
                 defaultMessage: '物模型',
@@ -68,6 +70,7 @@ const Metadata = observer(() => {
         </Tabs.TabPane>
       </Tabs>
       <Import visible={visible} close={() => setVisible(false)} />
+      <Cat visible={cat} close={() => setCat(false)} />
     </>
   );
 });

+ 24 - 6
src/pages/device/Product/service.ts

@@ -78,12 +78,30 @@ class Service extends BaseService<ProductItem> {
       map((resp) => resp.result),
     );
 
-  public convertMetadata = (type: string, data: any) => {
-    request(`${this.uri}/device/product/metadata/convert-from/${type}`, {
-      method: 'POST',
-      data,
-    });
-  };
+  public codecs = () =>
+    defer(() =>
+      from(
+        request(`/${SystemConst.API_BASE}/device/product/metadata/codecs`, {
+          method: 'GET',
+        }),
+      ),
+    ).pipe(
+      filter((resp) => resp.status === 200),
+      map((resp) => resp.result),
+    );
+
+  public convertMetadata = (direction: 'from' | 'to', type: string, data: any) =>
+    defer(() =>
+      from(
+        request(`/${SystemConst.API_BASE}/device/product/metadata/convert-${direction}/${type}`, {
+          method: 'POST',
+          data,
+        }),
+      ),
+    ).pipe(
+      filter((resp) => resp.status === 200),
+      map((resp) => resp.result),
+    );
 }
 
 export default Service;