Explorar el Código

fix: 引导页,告警仪表盘,其他

wzyyy hace 3 años
padre
commit
540e69b7f3

BIN
public/images/device/device-number.png


+ 41 - 37
src/pages/device/Instance/Detail/index.tsx

@@ -24,7 +24,7 @@ import SystemConst from '@/utils/const';
 import { getMenuPathByCode, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
 import { PermissionButton } from '@/components';
-import { ExclamationCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons';
+import {  QuestionCircleOutlined } from '@ant-design/icons';
 import Service from '@/pages/device/Instance/service';
 import useLocation from '@/hooks/route/useLocation';
 import { onlyMessage } from '@/utils/util';
@@ -107,21 +107,21 @@ const InstanceDetail = observer(() => {
         <Card>
           <Metadata
             type="device"
-            // tabAction={
-            //   <PermissionButton
-            //     isPermission={permission.update}
-            //     popConfirm={{
-            //       title: '确认重置?',
-            //       onConfirm: resetMetadata,
-            //     }}
-            //     tooltip={{
-            //       title: '重置后将使用产品的物模型配置',
-            //     }}
-            //     key={'reload'}
-            //   >
-            //     重置操作1
-            //   </PermissionButton>
-            // }
+          // tabAction={
+          //   <PermissionButton
+          //     isPermission={permission.update}
+          //     popConfirm={{
+          //       title: '确认重置?',
+          //       onConfirm: resetMetadata,
+          //     }}
+          //     tooltip={{
+          //       title: '重置后将使用产品的物模型配置',
+          //     }}
+          //     key={'reload'}
+          //   >
+          //     重置操作1
+          //   </PermissionButton>
+          // }
           />
         </Card>
       ),
@@ -250,6 +250,7 @@ const InstanceDetail = observer(() => {
   }, []);
 
   useEffect(() => {
+    // console.log(InstanceModel.current)
     if (!InstanceModel.current && !params.id) {
       history.goBack();
     } else {
@@ -308,6 +309,7 @@ const InstanceDetail = observer(() => {
               size={'small'}
               tooltip={{
                 title: InstanceModel.detail?.productName,
+                placement: 'topLeft'
               }}
               isPermission={!!getMenuPathByCode(MENUS_CODE['device/Product'])}
               onClick={() => {
@@ -391,12 +393,14 @@ const InstanceDetail = observer(() => {
                 断开连接
               </PermissionButton>
             )}
-            {InstanceModel.detail?.accessProvider === 'child-device' ? (
-              <div style={{ fontSize: 14, marginLeft: 10, fontWeight: 400 }}>
-                <ExclamationCircleOutlined style={{ fontSize: 14, marginRight: 5 }} />
-                {InstanceModel.detail?.features?.find((item) => item.id === 'selfManageState')
-                  ? '该设备的在线状态与父设备(网关设备)保持一致'
-                  : '该设备在线状态由设备自身运行状态决定,不继承父设备(网关设备)的在线状态'}
+            {InstanceModel.detail?.accessProvider === 'child-device' && InstanceModel.detail?.state?.value === "offline" ? (
+              <div>
+                <Tooltip placement='bottom'
+                  title={InstanceModel.detail?.features?.find((item) => item.id === 'selfManageState')
+                    ? '该设备的在线状态与父设备(网关设备)保持一致'
+                    : '该设备在线状态由设备自身运行状态决定,不继承父设备(网关设备)的在线状态'}>
+                  <QuestionCircleOutlined style={{ fontSize: 14, marginRight: 5 }} />
+                </Tooltip>
               </div>
             ) : (
               ''
@@ -404,21 +408,21 @@ const InstanceDetail = observer(() => {
           </Space>
         </div>
       }
-      // extra={[
-      //   statusMap[0],
-      //   <Button key="2">
-      //     {intl.formatMessage({
-      //       id: 'pages.device.productDetail.disable',
-      //       defaultMessage: '停用',
-      //     })}
-      //   </Button>,
-      //   <Button key="1" type="primary">
-      //     {intl.formatMessage({
-      //       id: 'pages.device.productDetail.setting',
-      //       defaultMessage: '应用配置',
-      //     })}
-      //   </Button>,
-      // ]}
+    // extra={[
+    //   statusMap[0],
+    //   <Button key="2">
+    //     {intl.formatMessage({
+    //       id: 'pages.device.productDetail.disable',
+    //       defaultMessage: '停用',
+    //     })}
+    //   </Button>,
+    //   <Button key="1" type="primary">
+    //     {intl.formatMessage({
+    //       id: 'pages.device.productDetail.setting',
+    //       defaultMessage: '应用配置',
+    //     })}
+    //   </Button>,
+    // ]}
     >
       {list.find((k) => k.key === InstanceModel.active)?.component}
     </PageContainer>

+ 54 - 39
src/pages/device/Product/Detail/Access/index.tsx

@@ -2,7 +2,7 @@ import { Badge, Button, Col, Empty, Row, Table, Tooltip } from 'antd';
 import { service } from '@/pages/link/AccessConfig';
 import { productModel, service as productService } from '@/pages/device/Product';
 import styles from './index.less';
-import type { SetStateAction } from 'react';
+import { SetStateAction, useRef } from 'react';
 import { useEffect, useState } from 'react';
 import AccessConfig from './AccessConfig';
 import ReactMarkdown from 'react-markdown';
@@ -56,6 +56,7 @@ const Access = () => {
   const [configVisible, setConfigVisible] = useState<boolean>(false);
 
   const [metadata, setMetadata] = useState<ConfigMetadata[]>([]);
+  const ref = useRef(0)
 
   const steps = [
     {
@@ -89,7 +90,7 @@ const Access = () => {
   ]
   const steps1 = [
     {
-      element: '#driver-config',
+      element: '.config',
       popover: {
         className: 'driver',
         title: `<div id='title'>填写配置</div><div id='guide'>1/4</div>`,
@@ -276,6 +277,10 @@ const Access = () => {
 
   const id = productModel.current?.id;
 
+  const guide = (data:any) =>{
+    service.productGuideSave(data)
+  }
+
   useEffect(() => {
     const driver = new Driver({
       allowClose: false,
@@ -283,36 +288,63 @@ const Access = () => {
       closeBtnText: '不在提示',
       nextBtnText: '下一步',
       prevBtnText: '上一步',
-      // onDeselected:(e)=>{
-      //   console.log(e)
-      // },
       onNext:()=>{
-        console.log('下一步')
+        ref.current=ref.current+1
+      },
+      onPrevious:()=>{
+        ref.current=ref.current-1
+      },
+      onReset:()=>{ 
+        if(ref.current!==3){
+          guide({
+            name:'guide',
+            content:'skip'
+          })
+        }
+        ref.current=0
+      },
+    });
+    const driver1 = new Driver({
+      allowClose: false,
+      doneBtnText: '我知道了',
+      closeBtnText: '不在提示',
+      nextBtnText: '下一步',
+      prevBtnText: '上一步',
+      onNext:()=>{
+        ref.current=ref.current+1
       },
       onPrevious:()=>{
-        console.log('上一步')
+        ref.current=ref.current-1
       },
       onReset:()=>{
-        console.log('关闭')
+        if(ref.current!==4){
+          guide({
+            name:'guide',
+            content:'skip'
+          })
+        }
+        ref.current=0
       },
-      // onDeselected:()=>{
-      //   console.log('oncolse')
-      // }
-    
     });
     setVisible(!!productModel.current?.accessId);
     if (productModel.current?.accessId) {
       if (id) {
         productService
           .getConfigMetadata(id)
-          .then((resp: { result: SetStateAction<ConfigMetadata[]> }) => {
+          .then(async (resp: { result: SetStateAction<ConfigMetadata[]> }) => {
             setMetadata(resp.result);
-            if (resp.result && resp.result.length > 0) {
-              driver.defineSteps(steps1)
-              driver.start();
-            } else {
-              driver.defineSteps(steps)
-              driver.start();
+            //判断引导页是否跳过
+            const res = await service.productGuide()
+            if(res.result && res.result?.content==='skip'){
+              return;
+            }else{
+              if (resp.result && resp.result.length > 0) {
+                driver1.defineSteps(steps1)
+                driver1.start();
+              } else {
+                driver.defineSteps(steps)
+                driver.start();
+              }
             }
           });
       }
@@ -337,23 +369,6 @@ const Access = () => {
     }
   }, [productModel.current]);
 
-  // useEffect(() => {
-  //   console.log(productModel.current)
-  //   console.log(productModel.current?.accessId)
-  //   const driver = new Driver({
-  //     allowClose: false,
-  //     doneBtnText: '我知道了',
-  //     closeBtnText: '不在提示',
-  //     nextBtnText: '下一步',
-  //     prevBtnText: '上一步'
-  //   });
-  //   if (productModel.current?.accessId) {
-  //     setTimeout(() => {
-  //       driver.defineSteps(steps)
-  //       driver.start();
-  //     }, 1000)
-  //   }
-  // }, [])
 
   const form = createForm({
     validateFirst: true,
@@ -485,9 +500,6 @@ const Access = () => {
     );
   };
 
-  // useEffect(() => {
-
-  // }, [])
 
   return (
     <div>
@@ -545,6 +557,9 @@ const Access = () => {
                           更换
                         </Button>
                       </Tooltip>
+                        {/* <Button onClick={async()=>{
+                          await service.productGuideDetail()
+                        }}>删除</Button> */}
                     </span>
                   }
                 />

+ 80 - 78
src/pages/home/device/index.tsx

@@ -1,6 +1,6 @@
 import { Col, message, Row, Tooltip } from 'antd';
 import { PermissionButton } from '@/components';
-import { Body } from '../components';
+import { Body, Guide } from '../components';
 import Statistics from '../components/Statistics';
 import Steps from '../components/Steps';
 import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
@@ -14,7 +14,7 @@ import DeviceChoose from '../components/DeviceChoose';
 const Device = () => {
   const productPermission = PermissionButton.usePermission('device/Product').permission;
   const devicePermission = PermissionButton.usePermission('device/Instance').permission;
-  // const rulePermission = PermissionButton.usePermission('rule-engine/Instance').permission;
+  const rulePermission = PermissionButton.usePermission('rule-engine/Instance').permission;
 
   const [productCount, setProductCount] = useState<number>(0);
   const [deviceCount, setDeviceCount] = useState<number>(0);
@@ -44,47 +44,88 @@ const Device = () => {
   const history = useHistory();
   // // 跳转
 
-  // const guideList = [
-  //   {
-  //     key: 'product',
-  //     name: '创建产品',
-  //     english: 'STEP1',
-  //     auth: !!productPermission.add,
-  //     url: 'device/Product',
-  //     param: {
-  //       save: true,
-  //     },
-  //   },
-  //   {
-  //     key: 'device',
-  //     name: '创建设备',
-  //     english: 'STEP2',
-  //     auth: !!devicePermission.add,
-  //     url: 'device/Instance',
-  //     param: {
-  //       save: true,
-  //     },
-  //   },
-  //   {
-  //     key: 'rule-engine',
-  //     name: '规则引擎',
-  //     english: 'STEP3',
-  //     auth: !!rulePermission.add,
-  //     url: 'rule-engine/Instance',
-  //     param: {
-  //       save: true,
-  //     },
-  //   },
-  // ];
+  const guideList = [
+    {
+      key: 'product',
+      name: '创建产品',
+      english: 'STEP1',
+      auth: !!productPermission.add,
+      url: 'device/Product',
+      param: {
+        save: true,
+      },
+    },
+    {
+      key: 'device',
+      name: '创建设备',
+      english: 'STEP2',
+      auth: !!devicePermission.add,
+      url: 'device/Instance',
+      param: {
+        save: true,
+      },
+    },
+    {
+      key: 'rule-engine',
+      name: '规则引擎',
+      english: 'STEP3',
+      auth: !!rulePermission.add,
+      url: 'rule-engine/Instance',
+      param: {
+        save: true,
+      },
+    },
+  ];
 
   return (
     <Row gutter={24}>
-      <Col span={18}>
+      <Col span={14}>
+        <Guide
+          title="物联网引导"
+          data={guideList}
+          // jump={(auth: boolean, url: string, param: string) => {
+          //   pageJump(auth, url, param);
+          // }}
+        />
+      </Col>
+      <Col span={10}>
+        <Statistics
+          data={[
+            {
+              name: '产品数量',
+              value: productCount,
+              children:require('/public/images/home/top-2.png'),
+            },
+            {
+              name: '设备数量',
+              value: deviceCount,
+              children: '',
+            },
+          ]}
+          title="设备统计"
+          extra={
+            <div style={{ fontSize: 14, fontWeight: 400 }}>
+              <a
+                onClick={() => {
+                  const url = getMenuPathByCode(MENUS_CODE['device/DashBoard']);
+                  if (!!url) {
+                    history.push(`${url}`);
+                  } else {
+                    message.warning('暂无权限,请联系管理员');
+                  }
+                }}
+              >
+                详情
+              </a>
+            </div>
+          }
+        />
+      </Col>
+      <Col span={24}>
+        <Body title={'平台架构图'} english={'PLATFORM ARCHITECTURE DIAGRAM'} />
+      </Col>
+      <Col span={24}>
         <Steps
-          style={{
-            height:275,
-            gridColumnGap:20
-          }}
           title={
             <span>
               设备接入推荐步骤
@@ -163,45 +204,6 @@ const Device = () => {
           ]}
         />
       </Col>
-      <Col span={6}>
-        <Statistics
-          style={{ gridTemplateColumns: 'repeat(1, 1fr)' }}
-          // height={448}
-          data={[
-            {
-              name: '产品数量',
-              value: productCount,
-              children: '',
-            },
-            {
-              name: '设备数量',
-              value: deviceCount,
-              children: '',
-            },
-          ]}
-          title="设备统计"
-          extra={
-            <div style={{ fontSize: 14, fontWeight: 400 }}>
-              <a
-                onClick={() => {
-                  const url = getMenuPathByCode(MENUS_CODE['device/DashBoard']);
-                  if (!!url) {
-                    history.push(`${url}`);
-                  } else {
-                    message.warning('暂无权限,请联系管理员');
-                  }
-                }}
-              >
-                详情
-              </a>
-            </div>
-          }
-        />
-      </Col>
-      <Col span={24} style={{marginTop:24}}>
-        <Body title={'平台架构图'} english={'PLATFORM ARCHITECTURE DIAGRAM'} />
-      </Col>
-
       <ProductChoose
         visible={productVisible}
         close={() => {

+ 70 - 79
src/pages/home/ops/index.tsx

@@ -1,5 +1,6 @@
 import { Col, message, Row, Tooltip } from 'antd';
-// import Guide from '../components/Guide';
+import Guide from '../components/Guide';
+import { PermissionButton } from '@/components';
 import Statistics from '../components/Statistics';
 import Pie from '@/pages/home/components/Pie';
 import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
@@ -15,9 +16,9 @@ const Ops = () => {
   const [subscribeTopic] = useSendWebsocketMessage();
   const history = useHistory();
 
-  // const accessPermission = getMenuPathByCode(MENUS_CODE['link/AccessConfig']);
-  // const logPermission = getMenuPathByCode(MENUS_CODE['Log']);
-  // const linkPermission = getMenuPathByCode(MENUS_CODE['link/DashBoard']);
+  const productPermission = PermissionButton.usePermission('device/Product').permission;
+  const devicePermission = PermissionButton.usePermission('device/Instance').permission;
+  const rulePermission = PermissionButton.usePermission('rule-engine/Instance').permission;
 
   const [cpuValue, setCpuValue] = useState<number>(0);
   const [jvmValue, setJvmValue] = useState<number>(0);
@@ -56,38 +57,73 @@ const Ops = () => {
       jvmRealTime?.unsubscribe();
     };
   }, []);
-
-  // const guideOpsList = [
-  //   {
-  //     key: 'access',
-  //     name: '设备接入配置',
-  //     english: 'DEVICE ACCESS CONFIGURATION',
-  //     auth: !!accessPermission,
-  //     url: accessPermission,
-  //   },
-  //   {
-  //     key: 'logger',
-  //     name: '日志排查',
-  //     english: 'LOG SCREEN',
-  //     auth: !!logPermission,
-  //     url: logPermission,
-  //     param: {
-  //       key: 'system',
-  //     },
-  //   },
-  //   {
-  //     key: 'realtime',
-  //     name: '实时监控',
-  //     english: 'REAL-TIME MONITORING',
-  //     auth: !!linkPermission,
-  //     url: linkPermission,
-  //     param: {
-  //       save: true,
-  //     },
-  //   },
-  // ];
+  const guideOpsList: any[] = [
+    {
+      key: 'product',
+      name: '设备接入配置',
+      english: 'STEP1',
+      auth: !!productPermission.add,
+      url: 'device/Product',
+      param: '?save=true',
+    },
+    {
+      key: 'device',
+      name: '日志排查',
+      english: 'STEP2',
+      auth: !!devicePermission.add,
+      url: 'device/Instance',
+      param: '?save=true',
+    },
+    {
+      key: 'rule-engine',
+      name: '实时监控',
+      english: 'STEP3',
+      auth: !!rulePermission.add,
+      url: 'rule-engine/Instance',
+      param: '?save=true',
+    },
+  ];
   return (
     <Row gutter={24}>
+      <Col span={14}>
+        <Guide title="运维引导" data={guideOpsList} />
+      </Col>
+      <Col span={10}>
+        <Statistics
+          data={[
+            {
+              name: 'CPU使用率',
+              value: String(cpuValue) + '%',
+              children: <Pie value={cpuValue} />,
+            },
+            {
+              name: 'JVM内存',
+              value: String(jvmValue) + '%',
+              children: <Pie value={jvmValue} />,
+            },
+          ]}
+          title="基础统计"
+          extra={
+            <div style={{ fontSize: 14, fontWeight: 400 }}>
+              <a
+                onClick={() => {
+                  const url = getMenuPathByCode(MENUS_CODE['device/DashBoard']);
+                  if (!!url) {
+                    history.push(`${url}`);
+                  } else {
+                    message.warning('暂无权限,请联系管理员');
+                  }
+                }}
+              >
+                详情
+              </a>
+            </div>
+          }
+        />
+      </Col>
+      <Col span={24}>
+        <Body title={'平台架构图'} english={'PLATFORM ARCHITECTURE DIAGRAM'} />
+      </Col>
       <Col span={24}>
         <Steps
           title={
@@ -169,51 +205,6 @@ const Ops = () => {
           ]}
         />
       </Col>
-      <Col span={18} style={{ marginTop: 24 }}>
-        <Body
-          title={'平台架构图'}
-          english={'PLATFORM ARCHITECTURE DIAGRAM'}
-          url={require('/public/images/home/content1.png')}
-        />
-      </Col>
-      <Col span={6} style={{ marginTop: 24 }}>
-        <Statistics
-          style={{ gridTemplateColumns: 'repeat(1, 1fr)' }}
-          height={448}
-          data={[
-            {
-              name: 'CPU使用率',
-              value: String(cpuValue) + '%',
-              children: <Pie value={cpuValue} />,
-            },
-            {
-              name: 'JVM内存',
-              value: String(jvmValue) + '%',
-              children: <Pie value={jvmValue} />,
-            },
-          ]}
-          title="基础统计"
-          extra={
-            <div style={{ fontSize: 14, fontWeight: 400 }}>
-              <a
-                onClick={() => {
-                  const url = getMenuPathByCode(MENUS_CODE['device/DashBoard']);
-                  if (!!url) {
-                    history.push(`${url}`);
-                  } else {
-                    message.warning('暂无权限,请联系管理员');
-                  }
-                }}
-              >
-                详情
-              </a>
-            </div>
-          }
-        />
-      </Col>
-      {/* <Col span={24}>
-        <Body title={'平台架构图'} english={'PLATFORM ARCHITECTURE DIAGRAM'} />
-      </Col> */}
     </Row>
   );
 };

+ 14 - 0
src/pages/link/AccessConfig/service.ts

@@ -51,6 +51,20 @@ class Service extends BaseService<AccessItem> {
     request(`/${SystemConst.API_BASE}/network/resources/clusters`, {
       method: 'GET',
     });
+  //引导页-不在提示
+  public productGuide = () =>
+    request(`/${SystemConst.API_BASE}/user/settings/product/guide`, {
+      method: 'GET',
+    })
+  public productGuideSave = (data: any) =>
+    request(`/${SystemConst.API_BASE}/user/settings/product/guide`, {
+      method: 'PATCH',
+      data
+    })
+    public productGuideDetail = () =>
+    request(`/${SystemConst.API_BASE}/user/settings/product/guide`, {
+      method: 'DELETE',
+    })
 }
 
 export default Service;

+ 54 - 16
src/pages/rule-engine/Alarm/Log/Detail/index.tsx

@@ -9,14 +9,18 @@ import { AlarmLogModel } from '../model';
 import { observer } from '@formily/reactive-react';
 import { SearchOutlined } from '@ant-design/icons';
 import Info from './Info';
-import { Button } from 'antd';
+import { Button, Card } from 'antd';
 import moment from 'moment';
+import useLocation from '@/hooks/route/useLocation';
+import { useDomFullHeight } from '@/hooks';
 
 const Detail = observer(() => {
   const params = useParams<{ id: string }>();
-
+  const location = useLocation();
   const [visible, setVisible] = useState<boolean>(false);
   const [current, setCurrent] = useState<Partial<AlarmLogHistoryItem>>({});
+  const { minHeight } = useDomFullHeight(`.alarm-log`,24);
+  const [detail, setDetail] = useState<any>({})
 
   const [param, setParam] = useState<any>({
     terms: [
@@ -91,6 +95,14 @@ const Detail = observer(() => {
     });
   }, [params.id]);
 
+  useEffect(() => {
+    const { state } = location;
+    setCurrent(detail)
+    if (state?.param.detail && detail) {
+      setVisible(true)
+    }
+  }, [location, detail]);
+
   return (
     <PageContainer>
       <SearchComponent<AlarmLogHistoryItem>
@@ -114,20 +126,46 @@ const Detail = observer(() => {
         }}
       />
       <ProTable<AlarmLogHistoryItem>
-        actionRef={actionRef}
-        params={param}
-        columns={AlarmLogModel.columns}
-        search={false}
-        scroll={{ x: 1366 }}
-        headerTitle={'记录列表'}
-        request={async (data) => {
-          return service.queryHistoryList({
-            ...data,
-            sorts: [{ name: 'alarmTime', order: 'desc' }],
-          });
-        }}
-        rowKey="id"
-      />
+          actionRef={actionRef}
+          params={param}
+          columns={AlarmLogModel.columns}
+          search={false}
+          tableClassName={'alarm-log'}
+          tableStyle={{ minHeight }}
+          scroll={{ x: 1366 }}
+          // headerTitle={'记录列表'}
+          request={async (data) => {
+            const res = await service.queryHistoryList({
+              ...data,
+              sorts: [{ name: 'alarmTime', order: 'desc' }],
+            });
+            if (res.status === 200) {
+              setDetail(res.result.data[0])
+              return {
+                code: res.message,
+                result: {
+                  data: res.result.data,
+                  pageIndex: res.result.pageIndex,
+                  pageSize: res.result.pageSize,
+                  total: res.result.total,
+                },
+                status: res.status,
+              };
+            } else {
+              return {
+                code: 200,
+                result: {
+                  data: [],
+                  pageIndex: 0,
+                  pageSize: 0,
+                  total: 0,
+                },
+                status: 200,
+              };
+            }
+          }}
+          rowKey="id"
+        />
       {visible && (
         <Info
           close={() => {

+ 25 - 6
src/pages/rule-engine/DashBoard/index.tsx

@@ -11,6 +11,8 @@ import styles from './index.less';
 import moment from 'moment';
 import Echarts from '@/components/DashBoard/echarts';
 import encodeQuery from '@/utils/encodeQuery';
+import useHistory from '@/hooks/route/useHistory';
+import { getMenuPathByCode } from '@/utils/menu';
 
 const service = new Service();
 export const state = model<{
@@ -43,6 +45,7 @@ type RefType = {
 };
 const Dashboard = observer(() => {
   const [options, setOptions] = useState<EChartsOption>({});
+  const history = useHistory();
 
   // 今日告警
   const today = {
@@ -253,9 +256,10 @@ const Dashboard = observer(() => {
           },
         },
         grid: {
-          left: '3%',
-          right: '4%',
-          bottom: '3%',
+          left: 0,
+          right: '1%',
+          bottom: 0,
+          top: '2%',
           containLabel: true,
         },
         xAxis: [
@@ -276,7 +280,10 @@ const Dashboard = observer(() => {
           {
             name: 'Direct',
             type: 'bar',
-            barWidth: '60%',
+            barWidth: '30%',
+            itemStyle: {
+              color: '#2F54EB',
+            },
             data: sData.reverse(),
           },
         ],
@@ -325,10 +332,22 @@ const Dashboard = observer(() => {
                         <div className={'new-alarm-item'}>
                           <div className={'new-alarm-item-time'}>
                             <img src={require('/public/images/alarm/bashboard.png')} alt="" />
-                            {moment(item.alarmTime).format('YYYY-MM-DD hh:mm:ss')}
+                            {moment(item.alarmTime).format('YYYY-MM-DD HH:mm:ss')}
                           </div>
                           <div className={'new-alarm-item-content ellipsis'}>
-                            <Tooltip title={item.alarmName}>{item.alarmName}</Tooltip>
+                            <Tooltip title={item.alarmName} placement='topLeft'>
+                              <a onClick={() => {
+                                console.log(item)
+                                const url = getMenuPathByCode('rule-engine/Alarm/Log');
+                                history.push(`${url}/detail/${item.id}`,{
+                                  param: {
+                                    detail: true,
+                                  },
+                                });
+                              }}>
+                                {item.alarmName}
+                              </a>
+                            </Tooltip>
                           </div>
                           <div className={'new-alarm-item-state'}>
                             <Badge