lind 3 лет назад
Родитель
Сommit
2f8277f4db

+ 6 - 2
src/components/DashBoard/baseCard.tsx

@@ -4,11 +4,12 @@ import type { EchartsProps } from './echarts';
 import Echarts from './echarts';
 import Style from './index.less';
 import classNames from 'classnames';
-import { forwardRef } from 'react';
+import React, { forwardRef } from 'react';
 
 interface BaseCardProps extends HeaderProps, EchartsProps {
   height: number;
   className?: string;
+  echartsAfter?: React.ReactNode;
 }
 
 export default forwardRef((props: BaseCardProps, ref) => {
@@ -22,7 +23,10 @@ export default forwardRef((props: BaseCardProps, ref) => {
       }}
     >
       <Header ref={ref} {...formProps} />
-      <Echarts options={options} className={Style['echarts']} />
+      <div className={Style['echarts-content']}>
+        <Echarts options={options} className={Style['echarts']} />
+        {props.echartsAfter}
+      </div>
     </div>
   );
 });

+ 4 - 3
src/components/DashBoard/echarts.tsx

@@ -1,4 +1,4 @@
-import { useEffect, useRef } from 'react';
+import { useCallback, useEffect, useRef } from 'react';
 import * as echarts from 'echarts/core';
 import type { ECharts, EChartsOption } from 'echarts';
 import {
@@ -72,11 +72,12 @@ export default (props: EchartsProps) => {
     }
   };
 
-  const updateOptions = () => {
+  const updateOptions = useCallback(() => {
+    console.log(chartsRef.current, props.options);
     if (chartsRef.current && props.options) {
       chartsRef.current.setOption(props.options);
     }
-  };
+  }, [props.options]);
 
   useEffect(() => {
     (window as Window).addEventListener('resize', updateSize);

+ 7 - 1
src/components/DashBoard/index.less

@@ -26,8 +26,14 @@
   height: 100%;
 }
 
-.echarts {
+.echarts-content {
+  display: flex;
   flex-grow: 1;
   height: 0;
   margin-top: 12px;
 }
+
+.echarts {
+  flex: 1;
+  height: 100%;
+}

+ 6 - 2
src/components/ProTableCard/CardItems/noticeTemplate.tsx

@@ -66,7 +66,9 @@ export default (props: NoticeCardProps) => {
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
             <span className={'card-item-header-name ellipsis'}>
-              <Tooltip title={props.name}>{props.name}</Tooltip>
+              <Tooltip placement="topLeft" title={props.name}>
+                {props.name}
+              </Tooltip>
             </span>
           </div>
           <div className={'card-item-content'}>
@@ -77,7 +79,9 @@ export default (props: NoticeCardProps) => {
             <div>
               <label>说明</label>
               <div className={'ellipsis'}>
-                <Tooltip title={props.description}>{props.description}</Tooltip>
+                <Tooltip placement="topLeft" title={props.description}>
+                  {props.description}
+                </Tooltip>
               </div>
             </div>
           </div>

+ 7 - 1
src/pages/account/NotificationSubscription/save/index.tsx

@@ -185,7 +185,13 @@ const Save = (props: Props) => {
   };
 
   return (
-    <Modal title={'详情'} visible onCancel={props.close} onOk={() => handleSave()} width={'45vw'}>
+    <Modal
+      title={props.data.id ? '编辑' : '新增'}
+      visible
+      onCancel={props.close}
+      onOk={() => handleSave()}
+      width={'45vw'}
+    >
       <Form form={form} layout="vertical">
         <SchemaField
           schema={schema}

+ 0 - 2
src/pages/device/Instance/Detail/MetadataLog/Property/index.tsx

@@ -223,8 +223,6 @@ const PropertyLog = (props: Props) => {
   useEffect(() => {
     setRadioValue('today');
     setTab('table');
-    setStart(moment().startOf('day').valueOf());
-    setEnd(new Date().getTime());
   }, []);
 
   const renderComponent = (type: string) => {

+ 1 - 1
src/pages/device/Instance/Detail/Running/Property/PropertyCard.tsx

@@ -49,7 +49,7 @@ const Property = (props: Props) => {
           <Tooltip title={title}>{title}</Tooltip>
         </div>
         <Space style={{ fontSize: 12 }}>
-          {(data.expands?.readOnly === false || data.expands?.readOnly === 'false') && (
+          {data.expands?.type.includes('write') && (
             <Tooltip placement="top" title="设置属性至设备">
               <EditOutlined
                 onClick={() => {

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

@@ -196,6 +196,8 @@ const Property = (props: Props) => {
     if (dataSource.data.length > 0) {
       getDashboard();
       subscribeProperty();
+    } else {
+      setLoading(false);
     }
   }, [dataSource]);
 

+ 4 - 0
src/pages/device/Product/Save/index.tsx

@@ -87,6 +87,10 @@ const Save = (props: Props) => {
         }
         props.close();
         form.resetFields();
+        if ((window as any).onTabSaveSuccess) {
+          (window as any).onTabSaveSuccess(res);
+          setTimeout(() => window.close(), 300);
+        }
       }
     }
   };

+ 10 - 1
src/pages/device/Product/index.tsx

@@ -12,7 +12,7 @@ import {
 import Service from '@/pages/device/Product/service';
 import { observer } from '@formily/react';
 import { model } from '@formily/reactive';
-import { useHistory } from 'umi';
+import { useHistory, useLocation } from 'umi';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import { useEffect, useRef, useState } from 'react';
@@ -78,6 +78,15 @@ const Product = observer(() => {
     ),
   };
 
+  const location = useLocation();
+
+  useEffect(() => {
+    if ((location as any).query?.save === 'true') {
+      setCurrent(undefined);
+      setVisible(true);
+    }
+  }, []);
+
   const deleteItem = async (id: string) => {
     const response: any = await service.remove(id);
     if (response.status === 200) {

+ 36 - 0
src/pages/home/components/Guide.tsx

@@ -0,0 +1,36 @@
+import { Card, Col, Row } from 'antd';
+
+interface Props {
+  title: string;
+  data: any[];
+  jump?: (auth: boolean, url: string, param: string) => void;
+}
+
+const Guide = (props: Props) => {
+  const { title, data, jump } = props;
+  return (
+    <Card>
+      <div style={{ marginBottom: 15 }}>
+        <h3>{title}</h3>
+      </div>
+      <Row gutter={24}>
+        {data.map((item) => (
+          <Col key={item.key} span={8}>
+            <Card
+              bordered
+              onClick={() => {
+                if (jump) {
+                  jump(item.auth, item.url, item.param);
+                }
+              }}
+            >
+              {item.name}
+            </Card>
+          </Col>
+        ))}
+      </Row>
+    </Card>
+  );
+};
+
+export default Guide;

+ 29 - 0
src/pages/home/components/Statistics.tsx

@@ -0,0 +1,29 @@
+import { Card, Col, Row } from 'antd';
+
+const Statistics = () => {
+  return (
+    <Card
+      title={'设备统计'}
+      extra={
+        <a
+          onClick={() => {
+            // pageJump(!!getMenuPathByCode('device/DashBoard'), 'device/DashBoard');
+          }}
+        >
+          详情
+        </a>
+      }
+    >
+      <Row gutter={24}>
+        <Col span={12}>
+          <Card bordered>产品数量</Card>
+        </Col>
+        <Col span={12}>
+          <Card bordered>设备数量</Card>
+        </Col>
+      </Row>
+    </Card>
+  );
+};
+
+export default Statistics;

+ 68 - 0
src/pages/home/components/Steps.tsx

@@ -0,0 +1,68 @@
+import { RightOutlined } from '@ant-design/icons';
+import { Card, Col, Row } from 'antd';
+
+const Steps = () => {
+  return (
+    <Card title={'设备接入推荐步骤'}>
+      <Row gutter={24}>
+        <Col span={4}>
+          <Card
+            bordered
+            title="创建产品"
+            onClick={() => {
+              // pageJump(!!devicePermission.add, 'device/Instance')
+            }}
+          >
+            产品是设备的集合,通常指一组具有相同功能的设备。物联设备必须通过产品进行接入方式配置。
+          </Card>
+        </Col>
+        <Col span={1}>
+          <RightOutlined />
+        </Col>
+        <Col span={4}>
+          <Card bordered title="配置产品接入方式" onClick={() => {}}>
+            通过产品对同一类型的所有设备进行统一的接入方式配置。请参照设备铭牌说明选择匹配的接入方式。
+          </Card>
+        </Col>
+        <Col span={1}>
+          <RightOutlined />
+        </Col>
+        <Col span={4}>
+          <Card
+            bordered
+            title="添加测试设备"
+            onClick={() => {
+              // pageJump(!!devicePermission.add, 'device/Instance')
+            }}
+          >
+            添加单个设备,用于验证产品模型是否配置正确。
+          </Card>
+        </Col>
+        <Col span={1}>
+          <RightOutlined />
+        </Col>
+        <Col span={4}>
+          <Card bordered title="功能调试" onClick={() => {}}>
+            对添加的测试设备进行功能调试,验证能否连接到平台,设备功能是否配置正确。
+          </Card>
+        </Col>
+        <Col span={1}>
+          <RightOutlined />
+        </Col>
+        <Col span={4}>
+          <Card
+            bordered
+            title="批量添加设备"
+            onClick={() => {
+              // pageJump(!!devicePermission.add, 'device/Instance')
+            }}
+          >
+            批量添加同一产品下的设备
+          </Card>
+        </Col>
+      </Row>
+    </Card>
+  );
+};
+
+export default Steps;

+ 97 - 1
src/pages/home/device/index.tsx

@@ -1,4 +1,100 @@
+import { Card, Col, message, Row } from 'antd';
+import { PermissionButton } from '@/components';
+import { getMenuPathByCode } from '@/utils/menu';
+import Guide from '../components/Guide';
+import Statistics from '../components/Statistics';
+import Steps from '../components/Steps';
+
 const Device = () => {
-  return <div>设备接入视图</div>;
+  const productPermission = PermissionButton.usePermission('device/Product').permission;
+  const devicePermission = PermissionButton.usePermission('device/Instance').permission;
+  const rulePermission = PermissionButton.usePermission('rule-engine/Instance').permission;
+  // // 跳转
+  const pageJump = (auth: boolean, url: string, param: string) => {
+    if (auth) {
+      // 判断是否有权限
+      const path = getMenuPathByCode(url);
+      if (path) {
+        const tab: any = window.open(`${origin}/#${path}${param}`);
+        tab!.onTabSaveSuccess = () => {
+          // if (value.status === 200) {
+          // }
+        };
+      }
+    } else {
+      message.error('暂无权限,请联系管理员');
+    }
+  };
+
+  const guideList = [
+    {
+      key: 'product',
+      name: '1、创建产品',
+      auth: !!productPermission.add,
+      url: 'device/Product',
+      param: '?save=true',
+    },
+    {
+      key: 'device',
+      name: '2、创建设备',
+      auth: !!devicePermission.add,
+      url: 'device/Instance',
+      param: '?save=true',
+    },
+    {
+      key: 'rule-engine',
+      name: '3、规则引擎',
+      auth: !!rulePermission.add,
+      url: 'rule-engine/Instance',
+      param: '?save=true',
+    },
+  ];
+
+  // const statisticsList = [{
+  //   key: 'product',
+  //   name: '1、创建产品',
+  //   auth: !!productPermission.add,
+  //   url: 'device/Product',
+  //   param: "?save=true"
+  // }, {
+  //   key: 'device',
+  //   name: '2、创建设备',
+  //   auth: !!devicePermission.add,
+  //   url: 'device/Instance',
+  //   param: "?save=true"
+  // },
+  // {
+  //   key: 'rule-engine',
+  //   name: '3、规则引擎',
+  //   auth: !!rulePermission.add,
+  //   url: 'rule-engine/Instance',
+  //   param: "?save=true"
+  // }
+  // ];
+
+  return (
+    <Row gutter={24}>
+      <Col span={12}>
+        <Guide
+          title="物联网引导"
+          data={guideList}
+          jump={(auth: boolean, url: string, param: string) => {
+            pageJump(auth, url, param);
+          }}
+        />
+      </Col>
+      <Col span={12}>
+        <Statistics />
+      </Col>
+      <Col span={24}>
+        <Card style={{ margin: '20px 0' }} title="平台架构图">
+          <img style={{ height: 500 }} src={require('/public/images/login.png')} />
+        </Card>
+      </Col>
+      <Col span={24}>
+        <Steps />
+      </Col>
+    </Row>
+  );
 };
 export default Device;

+ 7 - 0
src/pages/link/Certificate/index.tsx

@@ -25,6 +25,13 @@ const Certificate = () => {
       dataIndex: 'type',
       title: '证书标准',
       render: (text: any) => <span>{text?.text || '-'}</span>,
+      valueType: 'select',
+      valueEnum: {
+        common: {
+          text: '国际标准',
+          status: 'common',
+        },
+      },
     },
     {
       dataIndex: 'name',

+ 30 - 0
src/pages/link/DashBoard/index.less

@@ -0,0 +1,30 @@
+.link-dash-board {
+  background-color: #fff;
+
+  .echarts-items {
+    position: relative;
+    display: flex;
+    gap: 12px;
+    margin: 12px 0;
+
+    .echarts-item {
+      display: flex;
+      flex-grow: 1;
+      align-items: center;
+      justify-content: center;
+      width: 0;
+      height: 160px;
+
+      .echarts-item-title {
+        margin-bottom: 8px;
+        color: rgba(#000, 0.6);
+        font-size: 16px;
+      }
+
+      .echarts-item-value {
+        font-weight: bold;
+        font-size: 18px;
+      }
+    }
+  }
+}

+ 351 - 38
src/pages/link/DashBoard/index.tsx

@@ -1,10 +1,14 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import DashBoard from '@/components/DashBoard';
-import { Radio, Select } from 'antd';
+import { Progress, Radio, Select } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 import type { EChartsOption } from 'echarts';
 import { useRequest } from 'umi';
 import Service from './service';
+import moment from 'moment';
+import './index.less';
+import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
+import { map } from 'rxjs/operators';
 
 type RefType = {
   getValues: Function;
@@ -13,23 +17,136 @@ type RefType = {
 const service = new Service('dashboard');
 
 export default () => {
-  const [networkOptions] = useState<EChartsOption | undefined>(undefined);
-  const [cpuOptions] = useState<EChartsOption | undefined>(undefined);
-  const [jvmOptions] = useState<EChartsOption | undefined>(undefined);
+  const [networkOptions, setNetworkOptions] = useState<EChartsOption | undefined>(undefined);
+  const [cpuOptions, setCpuOptions] = useState<EChartsOption | undefined>(undefined);
+  const [jvmOptions, setJvmOptions] = useState<EChartsOption | undefined>(undefined);
   const [serverId, setServerId] = useState(undefined);
 
+  const [topValues, setTopValues] = useState({
+    cpu: 0,
+    jvm: 0,
+    usage: 0,
+    systemUsage: 0,
+  });
+
   const NETWORKRef = useRef<RefType>(); // 网络流量
   const CPURef = useRef<RefType>(); // CPU使用率
   const JVMRef = useRef<RefType>(); // JVM内存使用率
 
+  const [subscribeTopic] = useSendWebsocketMessage();
+
   const { data: serverNode } = useRequest(service.serverNode, {
     formatResult: (res) => res.result.map((item: any) => ({ label: item.name, value: item.id })),
   });
 
-  const getNetworkEcharts = () => {
-    const data = NETWORKRef.current!.getValues();
-    if (data) {
-      service.queryMulti([
+  const handleNetworkOptions = (data: Record<string, any>) => {
+    setNetworkOptions({
+      xAxis: {
+        type: 'category',
+        data: Object.keys(data),
+      },
+      tooltip: {
+        trigger: 'axis',
+      },
+      yAxis: {
+        type: 'value',
+      },
+      grid: {
+        left: '3%',
+        right: '2%',
+      },
+      series: [
+        {
+          data: Object.values(data),
+          type: 'line',
+        },
+      ],
+    });
+  };
+
+  const handleJVMOptions = (data: Record<string, any>) => {
+    setJvmOptions({
+      xAxis: {
+        type: 'category',
+        data: Object.keys(data).map((item) => {
+          return moment(Number(item)).format('YYYY-MM-DD HH:mm:ss');
+        }),
+      },
+      tooltip: {
+        trigger: 'axis',
+      },
+      yAxis: {
+        type: 'value',
+      },
+      grid: {
+        left: '3%',
+        right: '2%',
+      },
+      dataZoom: [
+        {
+          type: 'inside',
+          start: 0,
+          end: 10,
+        },
+        {
+          start: 0,
+          end: 10,
+        },
+      ],
+      series: [
+        {
+          data: Object.values(data),
+          type: 'line',
+        },
+      ],
+    });
+  };
+
+  const handleCpuOptions = (data: Record<string, any>) => {
+    setCpuOptions({
+      xAxis: {
+        type: 'category',
+        data: Object.keys(data).map((item) => {
+          return moment(Number(item)).format('YYYY-MM-DD HH:mm:ss');
+        }),
+      },
+      tooltip: {
+        trigger: 'axis',
+      },
+      yAxis: {
+        type: 'value',
+      },
+      grid: {
+        left: '3%',
+        right: '2%',
+      },
+      dataZoom: [
+        {
+          type: 'inside',
+          start: 0,
+          end: 10,
+        },
+        {
+          start: 0,
+          end: 10,
+        },
+      ],
+      series: [
+        {
+          data: Object.values(data),
+          type: 'line',
+        },
+      ],
+    });
+  };
+
+  const getAllEcharts = () => {
+    const networkData = NETWORKRef.current!.getValues();
+    const cpuData = CPURef.current!.getValues();
+    const jvmData = JVMRef.current!.getValues();
+
+    service
+      .queryMulti([
         {
           dashboard: 'systemMonitor',
           object: 'network',
@@ -37,57 +154,195 @@ export default () => {
           dimension: 'agg',
           group: 'network',
           params: {
-            type: data.type,
-            from: data.time.start,
-            to: data.time.end,
+            type: networkData.type,
+            interval: networkData.time.type === 'today' ? '1h' : '1d',
+            from: networkData.time.start,
+            to: networkData.time.end,
           },
         },
-      ]);
-    }
-  };
-
-  const getCPUEcharts = () => {
-    const data = CPURef.current!.getValues();
-    if (data) {
-      service.queryMulti([
         {
           dashboard: 'systemMonitor',
           object: 'stats',
-          measurement: 'traffic',
-          dimension: 'agg',
+          measurement: 'info',
+          dimension: 'history',
           group: 'cpu',
           params: {
-            from: data.time.start,
-            to: data.time.end,
+            from: cpuData.time.start,
+            to: cpuData.time.end,
           },
         },
-      ]);
-    }
-  };
-
-  const getJVMEcharts = () => {
-    const data = CPURef.current!.getValues();
-    if (data) {
-      service.queryMulti([
         {
           dashboard: 'systemMonitor',
           object: 'stats',
-          measurement: 'traffic',
-          dimension: 'agg',
+          measurement: 'info',
+          dimension: 'history',
           group: 'jvm',
           params: {
-            from: data.time.start,
-            to: data.time.end,
+            from: jvmData.time.start,
+            to: jvmData.time.end,
           },
         },
-      ]);
+      ])
+      .then((res) => {
+        if (res.status === 200) {
+          const _networkOptions = {};
+          const _jvmOptions = {};
+          const _cpuOptions = {};
+
+          res.result.forEach((item: any) => {
+            const value = item.data.value;
+            if (item.group === 'network') {
+              value.forEach((networkItem: any) => {
+                _networkOptions[networkItem.timeString] = networkItem.value;
+              });
+            } else if (item.group === 'cpu') {
+              const memoryJvmHeapFree = value.memoryJvmHeapFree;
+              const memoryJvmHeapTotal = value.memoryJvmHeapTotal;
+              _jvmOptions[value.timestamp] = (
+                ((memoryJvmHeapTotal - memoryJvmHeapFree) / memoryJvmHeapTotal) *
+                100
+              ).toFixed(2);
+            } else {
+              _cpuOptions[value.timestamp] = value.cpuSystemUsage;
+            }
+          });
+          handleNetworkOptions(_networkOptions);
+          handleJVMOptions(_jvmOptions);
+          handleCpuOptions(_cpuOptions);
+        }
+      });
+  };
+
+  const getNetworkEcharts = () => {
+    const data = NETWORKRef.current!.getValues();
+    if (data) {
+      service
+        .queryMulti([
+          {
+            dashboard: 'systemMonitor',
+            object: 'network',
+            measurement: 'traffic',
+            dimension: 'agg',
+            group: 'network',
+            params: {
+              type: data.type,
+              interval: data.time.type === 'today' ? '1h' : '1d',
+              from: data.time.start,
+              to: data.time.end,
+            },
+          },
+        ])
+        .then((res) => {
+          if (res.status === 200) {
+            const _options = {};
+            res.result.forEach((item: any) => {
+              const value = item.data.value;
+              value.forEach((networkItem: any) => {
+                _options[networkItem.timeString] = networkItem.value;
+              });
+            });
+            handleNetworkOptions(_options);
+          }
+        });
+    }
+  };
+
+  const getCPUEcharts = () => {
+    const data = CPURef.current!.getValues();
+    if (data) {
+      service
+        .queryMulti([
+          {
+            dashboard: 'systemMonitor',
+            object: 'stats',
+            measurement: 'info',
+            dimension: 'history',
+            group: 'cpu',
+            params: {
+              from: data.time.start,
+              to: data.time.end,
+            },
+          },
+        ])
+        .then((res) => {
+          if (res.status === 200) {
+            const _options = {};
+            res.result.forEach((item: any) => {
+              const value = item.data.value;
+              _options[value.timestamp] = value.cpuSystemUsage;
+            });
+            handleCpuOptions(_options);
+          }
+        });
+    }
+  };
+
+  const getJVMEcharts = () => {
+    const data = JVMRef.current!.getValues();
+    if (data) {
+      service
+        .queryMulti([
+          {
+            dashboard: 'systemMonitor',
+            object: 'stats',
+            measurement: 'info',
+            dimension: 'history',
+            group: 'jvm',
+            params: {
+              from: data.time.start,
+              to: data.time.end,
+            },
+          },
+        ])
+        .then((res) => {
+          if (res.status === 200) {
+            const _options = {};
+            res.result.forEach((item: any) => {
+              const value = item.data.value;
+              const memoryJvmHeapFree = value.memoryJvmHeapFree;
+              const memoryJvmHeapTotal = value.memoryJvmHeapTotal;
+              _options[value.timestamp] = (
+                ((memoryJvmHeapTotal - memoryJvmHeapFree) / memoryJvmHeapTotal) *
+                100
+              ).toFixed(2);
+            });
+            handleJVMOptions(_options);
+          }
+        });
     }
   };
 
   useEffect(() => {
     if (serverId) {
-      getNetworkEcharts();
+      getAllEcharts();
     }
+
+    const id = 'operations-statistics-system-info-realTime';
+    const topic = '/dashboard/systemMonitor/stats/info/realTime';
+    const sub = subscribeTopic!(id, topic, {
+      type: 'all',
+      serverNodeId: serverId,
+      interval: '5s',
+      agg: 'avg',
+    })
+      ?.pipe(map((res) => res.payload))
+      .subscribe((plyload: any) => {
+        const value = plyload.value;
+        const cpu = value.cpu;
+        const memory = value.memory;
+        const disk = value.disk;
+
+        setTopValues({
+          cpu: cpu.systemUsage,
+          jvm: memory.jvmHeapUsage,
+          usage: disk.usage,
+          systemUsage: memory.systemUsage,
+        });
+      });
+
+    return () => {
+      sub?.unsubscribe();
+    };
   }, [serverId]);
 
   useEffect(() => {
@@ -98,7 +353,7 @@ export default () => {
 
   return (
     <PageContainer>
-      <div>
+      <div className={'link-dash-board'}>
         {serverNode && serverNode.length ? (
           <Select
             value={serverId}
@@ -109,6 +364,64 @@ export default () => {
             style={{ width: 300 }}
           />
         ) : null}
+        <div className={'echarts-items'}>
+          <div className={'echarts-item'}>
+            <Progress
+              type="circle"
+              strokeWidth={8}
+              width={160}
+              percent={topValues.cpu}
+              format={(percent) => (
+                <div>
+                  <div className={'echarts-item-title'}>CPU使用率</div>
+                  <div className={'echarts-item-value'}>{percent}%</div>
+                </div>
+              )}
+            />
+          </div>
+          <div className={'echarts-item'}>
+            <Progress
+              type="circle"
+              strokeWidth={8}
+              width={160}
+              percent={topValues.jvm}
+              format={(percent) => (
+                <div>
+                  <div className={'echarts-item-title'}>JVM内存</div>
+                  <div className={'echarts-item-value'}>{percent}%</div>
+                </div>
+              )}
+            />
+          </div>
+          <div className={'echarts-item'}>
+            <Progress
+              type="circle"
+              strokeWidth={8}
+              width={160}
+              percent={topValues.usage}
+              format={(percent) => (
+                <div>
+                  <div className={'echarts-item-title'}>磁盘占用率</div>
+                  <div className={'echarts-item-value'}>{percent}%</div>
+                </div>
+              )}
+            />
+          </div>
+          <div className={'echarts-item'}>
+            <Progress
+              type="circle"
+              strokeWidth={8}
+              width={160}
+              percent={topValues.systemUsage}
+              format={(percent) => (
+                <div>
+                  <div className={'echarts-item-title'}>系统内存</div>
+                  <div className={'echarts-item-value'}>{percent}%</div>
+                </div>
+              )}
+            />
+          </div>
+        </div>
         <div>
           <DashBoard
             title={'网络流量'}

+ 3 - 3
src/pages/media/Cascade/Channel/index.tsx

@@ -52,7 +52,7 @@ const Channel = () => {
           style={{ marginTop: 10, width: '100%' }}
           onClick={async () => {
             if (!!data) {
-              const resp: any = await service.editBindInfo(record.gbChannelId, {
+              const resp: any = await service.editBindInfo(record.id, {
                 gbChannelId: data,
               });
               if (resp.status === 200) {
@@ -88,7 +88,7 @@ const Channel = () => {
         <span>
           {text}
           <Popover
-            visible={popVisible === record.gbChannelId}
+            visible={popVisible === record.id}
             trigger="click"
             content={content(record)}
             title={
@@ -114,7 +114,7 @@ const Channel = () => {
               style={{ marginLeft: 10 }}
               onClick={() => {
                 setData('');
-                setPopvisible(record.gbChannelId);
+                setPopvisible(record.id);
               }}
             >
               <EditOutlined />

+ 0 - 160
src/pages/rule-engine/DashBoard/index.tsx

@@ -1,160 +0,0 @@
-import { PageContainer } from '@ant-design/pro-layout';
-import { EChartsOption } from 'echarts';
-import { useState } from 'react';
-import { Statistic, StatisticCard } from '@ant-design/pro-card';
-import { Card, Select } from 'antd';
-import './index.less';
-import Header from '@/components/DashBoard/header';
-import Echarts from '@/components/DashBoard/echarts';
-
-const imgStyle = {
-  display: 'block',
-  width: 42,
-  height: 42,
-};
-
-const Dashboard = () => {
-  const [options, setOptions] = useState<EChartsOption>({});
-
-  const getEcharts = async (params: any) => {
-    // 请求数据
-    console.log(params);
-
-    setOptions({
-      xAxis: {
-        type: 'category',
-        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
-      },
-      yAxis: {
-        type: 'value',
-      },
-      series: [
-        {
-          data: [150, 230, 224, 218, 135, 147, 260],
-          type: 'line',
-        },
-      ],
-    });
-  };
-
-  return (
-    <PageContainer>
-      <div style={{ display: 'flex' }}>
-        <StatisticCard
-          title="今日告警"
-          statistic={{
-            value: 75,
-            suffix: '次',
-          }}
-          chart={
-            <img
-              src="https://gw.alipayobjects.com/zos/alicdn/PmKfn4qvD/mubiaowancheng-lan.svg"
-              width="100%"
-              alt="进度条"
-            />
-          }
-          footer={
-            <>
-              <Statistic value={15.1} title="当月告警" suffix="次" layout="horizontal" />
-            </>
-          }
-          style={{ width: '24%', marginRight: '5px' }}
-        />
-        <StatisticCard
-          statistic={{
-            title: '告警配置',
-            value: 2176,
-            icon: (
-              <img
-                style={imgStyle}
-                src="https://gw.alipayobjects.com/mdn/rms_7bc6d8/afts/img/A*dr_0RKvVzVwAAAAAAAAAAABkARQnAQ"
-                alt="icon"
-              />
-            ),
-          }}
-          style={{ width: '25%', marginRight: '5px' }}
-          footer={
-            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
-              <Statistic value={76} title="正常" suffix="次" layout="horizontal" />
-              <Statistic value={76} title="禁用" suffix="次" layout="horizontal" />
-            </div>
-          }
-        />
-        <div style={{ width: '50%' }}>
-          <StatisticCard
-            title="最新告警"
-            statistic={{
-              // title: '最新告警'
-              value: undefined,
-            }}
-            chart={
-              <ul>
-                {[
-                  {
-                    dateTime: '2022-01-01 00:00:00',
-                    name: '一楼烟感告警',
-                    product: '产品',
-                    level: '1极告警',
-                  },
-                  {
-                    dateTime: '2022-01-01 00:00:00',
-                    name: '一楼烟感告警',
-                    product: '产品',
-                    level: '1极告警',
-                  },
-                  {
-                    dateTime: '2022-01-01 00:00:00',
-                    name: '一楼烟感告警',
-                    product: '产品',
-                    level: '1极告警',
-                  },
-                  {
-                    dateTime: '2022-01-01 00:00:00',
-                    name: '一楼烟感告警',
-                    product: '产品',
-                    level: '1极告警',
-                  },
-                ].map((item) => (
-                  <li>
-                    <div style={{ display: 'flex', justifyContent: 'space-between' }}>
-                      <div>{item.dateTime}</div>
-                      <div>{item.name}</div>
-                      <div>{item.product}</div>
-                      <div>{item.level}</div>
-                    </div>
-                  </li>
-                ))}
-              </ul>
-            }
-          />
-        </div>
-      </div>
-      <Card style={{ marginTop: 10 }}>
-        <div
-          // className={classNames(Style['dash-board-echarts'], className)}
-          style={{
-            height: 200,
-          }}
-        >
-          <Header
-            title={'告警统计'}
-            extraParams={{
-              key: 'test',
-              Children: (
-                <Select
-                  options={[
-                    { label: '设备', value: 'device' },
-                    { label: '产品', value: 'product' },
-                  ]}
-                ></Select>
-              ),
-            }}
-            onParamsChange={getEcharts}
-          />
-          <Echarts options={options} />
-        </div>
-      </Card>
-    </PageContainer>
-  );
-};
-export default Dashboard;

+ 1 - 1
src/pages/system/DataSource/index.tsx

@@ -130,7 +130,7 @@ const DataSource = observer(() => {
         <PermissionButton
           style={{ padding: 0 }}
           type="link"
-          isPermission={userPermission.update}
+          isPermission={userPermission.action}
           key="manage"
           onClick={() => {
             const url = getMenuPathByCode(MENUS_CODE[`system/DataSource/Management`]);

+ 1 - 0
src/pages/system/Role/Detail/UserManage/index.tsx

@@ -42,6 +42,7 @@ const UserManage = () => {
       }),
       align: 'center',
       dataIndex: 'username',
+      ellipsis: true,
     },
     {
       title: '创建时间',