فهرست منبع

feat(device): status

Lind 4 سال پیش
والد
کامیت
ce3157fed0

+ 6 - 31
src/pages/device/Instance/Detail/PropertyList/index.tsx

@@ -1,46 +1,21 @@
-import type { ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
 import { service } from '@/pages/device/Instance';
 import { useParams } from 'umi';
 import { Drawer } from 'antd';
 import encodeQuery from '@/utils/encodeQuery';
-import moment from 'moment';
 import type { PropertyMetadata } from '@/pages/device/Product/typings';
-
-type PropertyData = {
-  data: string;
-  date: string;
-};
+import columns from '@/pages/device/Instance/Detail/MetadataLog/columns';
 
 interface Props {
-  property: string;
   visible: boolean;
   close: () => void;
   data: Partial<PropertyMetadata>;
 }
 
-const PropertyList = (props: Props) => {
+const PropertyLog = (props: Props) => {
   const params = useParams<{ id: string }>();
-  const { property, visible, close, data } = props;
-  const columns: ProColumns<PropertyData>[] = [
-    {
-      dataIndex: 'index',
-      valueType: 'indexBorder',
-      width: 48,
-    },
-    {
-      dataIndex: 'timestamp',
-      title: '时间',
-      sorter: true,
-      width: 200,
-      renderText: (text: string) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
-    },
-    {
-      dataIndex: 'formatValue',
-      title: '数据',
-      copyable: true,
-    },
-  ];
+  const { visible, close, data } = props;
+
   return (
     <Drawer title={data.name} visible={visible} onClose={() => close()} width="45vw">
       <ProTable
@@ -51,7 +26,7 @@ const PropertyList = (props: Props) => {
             params.id,
             encodeQuery({
               ...param,
-              terms: { property: property },
+              terms: { property: data.id },
               sorts: { timestamp: 'desc' },
             }),
           )
@@ -64,4 +39,4 @@ const PropertyList = (props: Props) => {
     </Drawer>
   );
 };
-export default PropertyList;
+export default PropertyLog;

+ 54 - 7
src/pages/device/Instance/Detail/Running/Event.tsx

@@ -1,24 +1,71 @@
-import { SyncOutlined } from '@ant-design/icons';
-import { message } from 'antd';
+import { SyncOutlined, UnorderedListOutlined } from '@ant-design/icons';
+import { Badge, Divider, message, Tooltip } from 'antd';
 import ProCard from '@ant-design/pro-card';
-import type { EventMetadata } from '@/pages/device/Product/typings';
+import type { EventMetadata, ObserverMetadata } from '@/pages/device/Product/typings';
+import { useEffect, useRef, useState } from 'react';
+import { service } from '@/pages/device/Instance';
+import { useParams } from 'umi';
+import EventLog from '@/pages/device/Instance/Detail/MetadataLog/Event';
 
 interface Props {
-  data: Partial<EventMetadata>;
+  data: Partial<EventMetadata> & ObserverMetadata;
 }
 
+const eventLevel = new Map();
+eventLevel.set('ordinary', <Badge status="processing" text="普通" />);
+eventLevel.set('warn', <Badge status="warning" text="警告" />);
+eventLevel.set('urgent', <Badge status="error" text="紧急" />);
+
 const Event = (props: Props) => {
   const { data } = props;
+  const params = useParams<{ id: string }>();
+
+  const [count, setCount] = useState<number>(0);
+  const cacheCount = useRef<number>(count);
+  useEffect(() => {
+    if (data.id) {
+      service.getEventCount(params.id, data.id).then((resp) => {
+        if (resp.status === 200) {
+          setCount(resp.result?.total);
+          cacheCount.current = resp.result?.total;
+        }
+      });
+    }
+
+    data.subscribe((payload: unknown) => {
+      console.log('订阅到消息', payload);
+      if (payload) {
+        cacheCount.current = cacheCount.current + 1;
+        console.log(cacheCount.current, 'currnt');
+        setCount(cacheCount.current);
+      }
+    });
+  }, [data.id, params.id]);
+  const [visible, setVisible] = useState<boolean>(false);
+
   return (
     <ProCard
-      title={data.name}
-      extra={<SyncOutlined onClick={() => message.success('刷新')} />}
+      title={`${data.name}: ${count}`}
+      extra={
+        <>
+          <SyncOutlined onClick={() => message.success('刷新')} />
+          <Divider type="vertical" />
+          <Tooltip placement="top" title="详情">
+            <UnorderedListOutlined
+              onClick={() => {
+                setVisible(true);
+              }}
+            />
+          </Tooltip>
+        </>
+      }
       layout="center"
       bordered
       headerBordered
       colSpan={{ xs: 12, sm: 8, md: 6, lg: 6, xl: 6 }}
     >
-      <div style={{ height: 60 }}>{`${data.name}-事件`}</div>
+      <div style={{ height: 60 }}>{eventLevel.get(data.expands?.level || 'warn')}</div>
+      <EventLog visible={visible} close={() => setVisible(false)} data={data} />
     </ProCard>
   );
 };

+ 2 - 7
src/pages/device/Instance/Detail/Running/Property.tsx

@@ -6,7 +6,7 @@ import { Line } from '@ant-design/charts';
 import { useCallback, useEffect, useRef, useState } from 'react';
 import { service } from '@/pages/device/Instance';
 import { useParams } from 'umi';
-import PropertyList from '@/pages/device/Instance/Detail/PropertyList';
+import PropertyLog from '@/pages/device/Instance/Detail/PropertyLog';
 
 interface Props {
   data: Partial<PropertyMetadata> & ObserverMetadata;
@@ -156,12 +156,7 @@ const Property = (props: Props) => {
       <Spin spinning={loading}>
         <div style={{ height: 60 }}>{chart()}</div>
       </Spin>
-      <PropertyList
-        data={data}
-        property={data.id!}
-        visible={visible}
-        close={() => setVisible(false)}
-      />
+      <PropertyLog data={data} visible={visible} close={() => setVisible(false)} />
     </ProCard>
   );
 };

+ 27 - 11
src/pages/device/Instance/Detail/Running/index.tsx

@@ -2,6 +2,7 @@ import { InstanceModel, service } from '@/pages/device/Instance';
 import { Badge, Card, Col, Row } from 'antd';
 import type {
   DeviceMetadata,
+  EventMetadata,
   ObserverMetadata,
   PropertyMetadata,
 } from '@/pages/device/Product/typings';
@@ -43,24 +44,21 @@ const Running = () => {
   metadata.events = metadata.events.map(addObserver);
   metadata.properties = metadata.properties.map(addObserver);
   const [propertiesList, setPropertiesList] = useState<string[]>([]);
-  // const eventWS = {
-  //   id: `instance-info-event-${device.id}-${device.productId}`,
-  //   topic: `/dashboard/device/${device.productId}/events/realTime`,
-  // }
+
   useEffect(() => {
     const list = metadata.properties.map((item: any) => item.id);
     setPropertiesList(list);
   }, []);
-  const propertyWs = {
-    id: `instance-info-property-${device.id}-${device.productId}-${propertiesList.join('-')}`,
-    topic: `/dashboard/device/${device.productId}/properties/realTime`,
-  };
 
   /**
-   * 获取ws下发属性数据
+   * 订阅属性数据
    */
   const subscribeProperty = () => {
-    subscribeTopic!(propertyWs.id, propertyWs.topic, {
+    const id = `instance-info-property-${device.id}-${device.productId}-${propertiesList.join(
+      '-',
+    )}`;
+    const topic = `/dashboard/device/${device.productId}/properties/realTime`;
+    subscribeTopic!(id, topic, {
       deviceId: device.id,
       properties: propertiesList,
       history: 0,
@@ -102,8 +100,26 @@ const Running = () => {
       },
     });
   };
+
+  /**
+   * 订阅事件数据
+   */
+  const subscribeEvent = () => {
+    const id = `instance-info-event-${device.id}-${device.productId}`;
+    const topic = `/dashboard/device/${device.productId}/events/realTime`;
+    subscribeTopic!(id, topic, { deviceId: device.id })
+      ?.pipe(map((res) => res.payload))
+      .subscribe((payload: any) => {
+        const event = metadata.events.find((i) => i.id === payload.value.event) as EventMetadata &
+          ObserverMetadata;
+        if (event) {
+          event.next(payload);
+        }
+      });
+  };
   useEffect(() => {
     subscribeProperty();
+    subscribeEvent();
     getDashboard();
   }, []);
 
@@ -116,7 +132,7 @@ const Running = () => {
       )),
       ...metadata.events.map((item) => (
         <Col {...ColResponsiveProps} key={item.id}>
-          <Event data={item} />
+          <Event data={item as Partial<EventMetadata> & ObserverMetadata} />
         </Col>
       )),
     ];

+ 5 - 0
src/pages/device/Instance/service.ts

@@ -55,6 +55,11 @@ class Service extends BaseService<DeviceInstance> {
       method: 'GET',
       params,
     });
+
+  public getEventCount = (deviceId: string, eventId: string) =>
+    request(
+      `/${SystemConst.API_BASE}/device/instance/${deviceId}/event/${eventId}?format=true&pageSize=1`,
+    );
 }
 
 export default Service;