Sfoglia il codice sorgente

refactor(metadata): add device metadata

Lind 4 anni fa
parent
commit
6d577db923

+ 30 - 30
src/pages/device/Product/service.ts

@@ -1,5 +1,5 @@
 import BaseService from '@/utils/BaseService';
-import type { MetadataType, ProductItem } from '@/pages/device/Product/typings';
+import type { ProductItem } from '@/pages/device/Product/typings';
 import { request } from 'umi';
 import SystemConst from '@/utils/const';
 import { concatMap, defer, from, toArray } from 'rxjs';
@@ -36,35 +36,35 @@ class Service extends BaseService<ProductItem> {
       map((resp) => resp.result),
     );
 
-  public getMetadataConfig = (params: {
-    deviceId: string;
-    metadata: {
-      type: MetadataType | 'property';
-      id: string;
-      dataType: string;
-    };
-  }) =>
-    defer(() =>
-      from(
-        request(
-          `/${SystemConst.API_BASE}/device/product/${params.deviceId}/config-metadata/${params.metadata.type}/${params.metadata.id}/${params.metadata.dataType}`,
-        ),
-      ),
-    ).pipe(
-      filter((resp) => resp.status === 200),
-      map((resp) => resp.result),
-    );
-
-  public getUnit = () =>
-    request(`/${SystemConst.API_BASE}/protocol/units`, {
-      method: 'GET',
-    });
-
-  public saveProduct = (data: Record<string, unknown>) =>
-    request(`/${SystemConst.API_BASE}/device-product`, {
-      method: 'PATCH',
-      data,
-    });
+  // public getMetadataConfig = (params: {
+  //   deviceId: string;
+  //   metadata: {
+  //     type: MetadataType | 'property';
+  //     id: string;
+  //     dataType: string;
+  //   };
+  // }) =>
+  //   defer(() =>
+  //     from(
+  //       request(
+  //         `/${SystemConst.API_BASE}/device/product/${params.deviceId}/config-metadata/${params.metadata.type}/${params.metadata.id}/${params.metadata.dataType}`,
+  //       ),
+  //     ),
+  //   ).pipe(
+  //     filter((resp) => resp.status === 200),
+  //     map((resp) => resp.result),
+  //   );
+
+  // public getUnit = () =>
+  //   request(`/${SystemConst.API_BASE}/protocol/units`, {
+  //     method: 'GET',
+  //   });
+
+  // public saveProduct = (data: Record<string, unknown>) =>
+  //   request(`/${SystemConst.API_BASE}/device-product`, {
+  //     method: 'PATCH',
+  //     data,
+  //   });
 
   public changeDeploy = (id: string, state: 'deploy' | 'undeploy') =>
     defer(() =>

+ 41 - 15
src/pages/device/components/Metadata/Base/Edit/index.tsx

@@ -1,4 +1,4 @@
-import { Drawer, Dropdown, Menu, message } from 'antd';
+import { Button, Drawer, Dropdown, Menu, message } from 'antd';
 import { createSchemaField } from '@formily/react';
 import MetadataModel from '../model';
 import type { Field, IFieldState } from '@formily/core';
@@ -24,7 +24,8 @@ import {
   PropertySource,
 } from '@/pages/device/data';
 import { useCallback, useEffect, useState } from 'react';
-import { productModel, service } from '@/pages/device/Product';
+import { productModel } from '@/pages/device/Product';
+import { service } from '@/pages/device/components/Metadata';
 import { Store } from 'jetlinks-store';
 import type { MetadataItem, UnitType } from '@/pages/device/Product/typings';
 
@@ -39,8 +40,14 @@ import type { DeviceMetadata } from '@/pages/device/Product/typings';
 import SystemConst from '@/utils/const';
 import DB from '@/db';
 import _ from 'lodash';
+import { useParams } from 'umi';
+import { InstanceModel } from '@/pages/device/Instance';
 
-const Edit = () => {
+interface Props {
+  type: 'product' | 'device';
+}
+
+const Edit = (props: Props) => {
   const intl = useIntl();
   const form = createForm({
     initialValues: MetadataModel.item as Record<string, unknown>,
@@ -504,15 +511,21 @@ const Edit = () => {
     });
   }, [getUnits]);
 
+  const param = useParams<{ id: string }>();
+  const typeMap = new Map<string, any>();
+
+  typeMap.set('product', productModel.current);
+  typeMap.set('device', InstanceModel.detail);
+  const saveMap = new Map<string, Promise<any>>();
+  const { type } = MetadataModel;
+
   const saveMetadata = async (deploy?: boolean) => {
     const params = (await form.submit()) as MetadataItem;
-    const { type } = MetadataModel;
-    const product = productModel.current;
-    if (!product) return;
-    const metadata = JSON.parse(product.metadata) as DeviceMetadata;
+
+    if (!typeMap.get(props.type)) return;
+    const metadata = JSON.parse(typeMap.get(props.type).metadata) as DeviceMetadata;
     const config = metadata[type] as MetadataItem[];
     const index = config.findIndex((item) => item.id === params.id);
-    // todo 考虑优化
     if (index > -1) {
       config[index] = params;
       DB.getDB().table(`${type}`).update(params.id, params);
@@ -520,14 +533,21 @@ const Edit = () => {
       config.push(params);
       DB.getDB().table(`${type}`).add(params, params.id);
     }
-    // 保存到服务器
-    product.metadata = JSON.stringify(metadata);
-    const result = await service.saveProduct(product);
+
+    if (props.type === 'product') {
+      const product = typeMap.get('product');
+      product.metadata = JSON.stringify(metadata);
+      saveMap.set('product', service.saveProductMetadata(product));
+    } else {
+      saveMap.set('device', service.saveDeviceMetadata(param.id, metadata));
+    }
+
+    console.log(props.type, 'type', deploy);
+    const result = await saveMap.get(props.type);
     if (result.status === 200) {
       message.success('操作成功!');
       Store.set(SystemConst.REFRESH_METADATA_TABLE, true);
       if (deploy) {
-        // 不阻塞主流程。发布更新通知
         Store.set('product-deploy', deploy);
       }
       MetadataModel.edit = false;
@@ -563,9 +583,15 @@ const Edit = () => {
       zIndex={1000}
       placement={'right'}
       extra={
-        <Dropdown.Button type="primary" onClick={() => saveMetadata()} overlay={menu}>
-          保存数据
-        </Dropdown.Button>
+        props.type === 'product' ? (
+          <Dropdown.Button type="primary" onClick={() => saveMetadata()} overlay={menu}>
+            保存数据
+          </Dropdown.Button>
+        ) : (
+          <Button type="primary" onClick={() => saveMetadata()}>
+            保存数据
+          </Button>
+        )
       }
     >
       <Form form={form} layout="vertical" size="small">

+ 4 - 3
src/pages/device/components/Metadata/Base/index.tsx

@@ -16,10 +16,11 @@ import { useIntl } from '@@/plugin-locale/localeExports';
 
 interface Props {
   type: MetadataType;
+  target: 'product' | 'device';
 }
 
 const BaseMetadata = observer((props: Props) => {
-  const { type } = props;
+  const { type, target } = props;
   const intl = useIntl();
   const param = useParams<{ id: string }>();
 
@@ -95,7 +96,7 @@ const BaseMetadata = observer((props: Props) => {
         }}
         toolbar={{
           search: {
-            onSearch: (value) => {
+            onSearch: async (value) => {
               // Todo 物模型属性搜索
               message.success(value);
             },
@@ -120,7 +121,7 @@ const BaseMetadata = observer((props: Props) => {
           </Button>,
         ]}
       />
-      {MetadataModel.edit && <Edit />}
+      {MetadataModel.edit && <Edit type={target} />}
     </>
   );
 });

+ 6 - 4
src/pages/device/components/Metadata/index.tsx

@@ -6,12 +6,14 @@ import Import from './Import';
 import type { ReactNode } from 'react';
 import { useState } from 'react';
 import Cat from './Cat';
+import Service from '@/pages/device/components/Metadata/service';
 
 interface Props {
   tabAction?: ReactNode;
   type: 'product' | 'device';
 }
 
+export const service = new Service();
 const Metadata = observer((props: Props) => {
   const intl = useIntl();
   const [visible, setVisible] = useState<boolean>(false);
@@ -46,7 +48,7 @@ const Metadata = observer((props: Props) => {
           })}
           key="properties"
         >
-          <BaseMetadata type={'properties'} />
+          <BaseMetadata target={props.type} type={'properties'} />
         </Tabs.TabPane>
         <Tabs.TabPane
           tab={intl.formatMessage({
@@ -55,7 +57,7 @@ const Metadata = observer((props: Props) => {
           })}
           key="functions"
         >
-          <BaseMetadata type={'functions'} />
+          <BaseMetadata target={props.type} type={'functions'} />
         </Tabs.TabPane>
         <Tabs.TabPane
           tab={intl.formatMessage({
@@ -64,7 +66,7 @@ const Metadata = observer((props: Props) => {
           })}
           key="events"
         >
-          <BaseMetadata type={'events'} />
+          <BaseMetadata target={props.type} type={'events'} />
         </Tabs.TabPane>
         <Tabs.TabPane
           tab={intl.formatMessage({
@@ -73,7 +75,7 @@ const Metadata = observer((props: Props) => {
           })}
           key="tags"
         >
-          <BaseMetadata type={'tags'} />
+          <BaseMetadata target={props.type} type={'tags'} />
         </Tabs.TabPane>
       </Tabs>
       <Import visible={visible} close={() => setVisible(false)} />

+ 46 - 0
src/pages/device/components/Metadata/service.ts

@@ -0,0 +1,46 @@
+import BaseService from '@/utils/BaseService';
+import { request } from '@@/plugin-request/request';
+import SystemConst from '@/utils/const';
+import type { MetadataType } from '@/pages/device/Product/typings';
+import { defer, from } from 'rxjs';
+import { filter, map } from 'rxjs/operators';
+
+class Service extends BaseService<any> {
+  public saveProductMetadata = (data: Record<string, unknown>) =>
+    request(`/${SystemConst.API_BASE}/device-product`, {
+      method: 'PATCH',
+      data,
+    });
+
+  public saveDeviceMetadata = (id: string, data: Record<string, unknown>) =>
+    request(`/${SystemConst.API_BASE}/device/instance/${id}/metadata`, {
+      method: 'PUT',
+      data,
+    });
+
+  public getMetadataConfig = (params: {
+    deviceId: string;
+    metadata: {
+      type: MetadataType | 'property';
+      id: string;
+      dataType: string;
+    };
+  }) =>
+    defer(() =>
+      from(
+        request(
+          `/${SystemConst.API_BASE}/device/product/${params.deviceId}/config-metadata/${params.metadata.type}/${params.metadata.id}/${params.metadata.dataType}`,
+        ),
+      ),
+    ).pipe(
+      filter((resp) => resp.status === 200),
+      map((resp) => resp.result),
+    );
+
+  public getUnit = () =>
+    request(`/${SystemConst.API_BASE}/protocol/units`, {
+      method: 'GET',
+    });
+}
+
+export default Service;