瀏覽代碼

feat: merge

xieyonghong 3 年之前
父節點
當前提交
281ed02e3b
共有 100 個文件被更改,包括 827 次插入587 次删除
  1. 二進制
      public/images/northbound/doc1.png
  2. 二進制
      public/images/northbound/doc2.png
  3. 二進制
      public/images/northbound/doc3.png
  4. 22 3
      src/app.tsx
  5. 2 1
      src/components/Authorization/index.tsx
  6. 3 2
      src/components/BaseCrud/save/index.tsx
  7. 2 1
      src/components/BindUser/Bound.tsx
  8. 1 1
      src/components/DashBoard/timePicker.tsx
  9. 5 3
      src/components/Player/ScreenPlayer.tsx
  10. 1 1
      src/components/ProTableCard/CardItems/noticeTemplate.tsx
  11. 5 5
      src/components/SearchComponent/index.tsx
  12. 12 0
      src/global.less
  13. 3 3
      src/pages/Northbound/AliCloud/Detail/index.tsx
  14. 15 11
      src/pages/Northbound/AliCloud/index.tsx
  15. 5 1
      src/pages/Northbound/DuerOS/Detail/Doc.tsx
  16. 4 4
      src/pages/Northbound/DuerOS/Detail/index.tsx
  17. 7 6
      src/pages/Northbound/DuerOS/index.tsx
  18. 6 0
      src/pages/Northbound/DuerOS/service.ts
  19. 6 5
      src/pages/account/Center/bind/index.tsx
  20. 6 5
      src/pages/account/Center/index.tsx
  21. 3 2
      src/pages/account/NotificationRecord/index.tsx
  22. 6 5
      src/pages/account/NotificationSubscription/index.tsx
  23. 3 3
      src/pages/account/NotificationSubscription/save/index.tsx
  24. 3 2
      src/pages/cloud/Aliyun/index.tsx
  25. 3 2
      src/pages/cloud/Ctwing/index.tsx
  26. 3 2
      src/pages/cloud/Onenet/index.tsx
  27. 4 3
      src/pages/device/Alarm/index.tsx
  28. 4 3
      src/pages/device/Category/Save/index.tsx
  29. 3 3
      src/pages/device/Category/index.tsx
  30. 4 3
      src/pages/device/Command/create/index.tsx
  31. 4 3
      src/pages/device/Command/index.tsx
  32. 4 3
      src/pages/device/Firmware/Detail/Task/Release/index.tsx
  33. 4 3
      src/pages/device/Firmware/Detail/Task/Save/index.tsx
  34. 4 3
      src/pages/device/Firmware/Save/index.tsx
  35. 3 2
      src/pages/device/Firmware/index.tsx
  36. 4 3
      src/pages/device/Instance/Detail/ChildDevice/index.tsx
  37. 3 2
      src/pages/device/Instance/Detail/Config/Edit.tsx
  38. 4 3
      src/pages/device/Instance/Detail/Config/index.tsx
  39. 2 2
      src/pages/device/Instance/Detail/Diagnose/Status/DiagnosticAdvice.tsx
  40. 2 2
      src/pages/device/Instance/Detail/Diagnose/Status/ManualInspection.tsx
  41. 6 5
      src/pages/device/Instance/Detail/Diagnose/Status/index.tsx
  42. 2 2
      src/pages/device/Instance/Detail/Functions/AdvancedMode.tsx
  43. 3 2
      src/pages/device/Instance/Detail/MetadataMap/EditableTable/index.tsx
  44. 5 4
      src/pages/device/Instance/Detail/Modbus/index.tsx
  45. 5 4
      src/pages/device/Instance/Detail/Opcua/index.tsx
  46. 3 2
      src/pages/device/Instance/Detail/Reation/Edit.tsx
  47. 2 2
      src/pages/device/Instance/Detail/Running/Property/EditProperty.tsx
  48. 3 2
      src/pages/device/Instance/Detail/Running/Property/Indicators.tsx
  49. 3 2
      src/pages/device/Instance/Detail/Running/Property/PropertyCard.tsx
  50. 3 2
      src/pages/device/Instance/Detail/Running/Property/index.tsx
  51. 3 2
      src/pages/device/Instance/Detail/Tags/Edit.tsx
  52. 4 3
      src/pages/device/Instance/Detail/index.tsx
  53. 4 4
      src/pages/device/Instance/Import/index.tsx
  54. 3 2
      src/pages/device/Instance/Save/index.tsx
  55. 14 10
      src/pages/device/Instance/index.tsx
  56. 4 3
      src/pages/device/Product/Detail/Access/AccessConfig/index.tsx
  57. 3 2
      src/pages/device/Product/Detail/Access/index.tsx
  58. 4 4
      src/pages/device/Product/Detail/PropertyImport/index.tsx
  59. 2 1
      src/pages/device/Product/Detail/index.tsx
  60. 3 2
      src/pages/device/Product/Save/index.tsx
  61. 9 9
      src/pages/device/Product/index.tsx
  62. 3 2
      src/pages/device/components/Alarm/Edit/index.tsx
  63. 3 2
      src/pages/device/components/Alarm/Record/index.tsx
  64. 4 3
      src/pages/device/components/Alarm/Setting/index.tsx
  65. 2 1
      src/pages/device/components/Metadata/Base/Edit/index.tsx
  66. 3 3
      src/pages/device/components/Metadata/Base/index.tsx
  67. 5 4
      src/pages/device/components/Metadata/Import/index.tsx
  68. 3 2
      src/pages/device/components/Metadata/index.tsx
  69. 1 1
      src/pages/home/comprehensive/index.tsx
  70. 1 1
      src/pages/home/ops/index.tsx
  71. 37 0
      src/pages/link/AccessConfig/Detail/Access/data.ts
  72. 36 51
      src/pages/link/AccessConfig/Detail/Access/index.tsx
  73. 3 2
      src/pages/link/AccessConfig/Detail/Channel/index.tsx
  74. 3 2
      src/pages/link/AccessConfig/Detail/Cloud/Finish/index.tsx
  75. 3 3
      src/pages/link/AccessConfig/Detail/Cloud/index.tsx
  76. 5 5
      src/pages/link/AccessConfig/Detail/Media/index.tsx
  77. 6 5
      src/pages/link/AccessConfig/index.tsx
  78. 4 3
      src/pages/link/Certificate/Detail/components/CertificateFile/index.tsx
  79. 3 2
      src/pages/link/Certificate/Detail/index.tsx
  80. 3 2
      src/pages/link/Certificate/index.tsx
  81. 3 2
      src/pages/link/Channel/Modbus/Access/addPoint/index.tsx
  82. 4 3
      src/pages/link/Channel/Modbus/Access/bindDevice/index.tsx
  83. 5 4
      src/pages/link/Channel/Modbus/Access/index.tsx
  84. 4 4
      src/pages/link/Channel/Modbus/Save/index.tsx
  85. 4 3
      src/pages/link/Channel/Modbus/index.tsx
  86. 6 5
      src/pages/link/Channel/Opcua/Access/addPoint/index.tsx
  87. 4 3
      src/pages/link/Channel/Opcua/Access/bindDevice/index.tsx
  88. 5 4
      src/pages/link/Channel/Opcua/Access/index.tsx
  89. 4 4
      src/pages/link/Channel/Opcua/Save/index.tsx
  90. 5 4
      src/pages/link/Channel/Opcua/index.tsx
  91. 5 5
      src/pages/link/Gateway/index.tsx
  92. 3 2
      src/pages/link/Protocol/FileUpload/index.tsx
  93. 8 7
      src/pages/link/Protocol/index.tsx
  94. 3 3
      src/pages/link/Type/Detail/index.tsx
  95. 6 5
      src/pages/link/Type/index.tsx
  96. 4 3
      src/pages/media/Cascade/Channel/BindChannel/index.tsx
  97. 6 5
      src/pages/media/Cascade/Channel/index.tsx
  98. 35 0
      src/pages/media/Cascade/Save/index.less
  99. 322 252
      src/pages/media/Cascade/Save/index.tsx
  100. 0 0
      src/pages/media/Cascade/index.tsx

二進制
public/images/northbound/doc1.png


二進制
public/images/northbound/doc2.png


二進制
public/images/northbound/doc3.png


+ 22 - 3
src/app.tsx

@@ -13,7 +13,13 @@ import type { RequestOptionsInit } from 'umi-request';
 import ReconnectingWebSocket from 'reconnecting-websocket';
 import SystemConst from '@/utils/const';
 import { service as MenuService } from '@/pages/system/Menu';
-import getRoutes, { extraRouteArr, getMenus, handleRoutes, saveMenusCache } from '@/utils/menu';
+import getRoutes, {
+  extraRouteArr,
+  getMenuPathByCode,
+  getMenus,
+  handleRoutes,
+  saveMenusCache,
+} from '@/utils/menu';
 import { AIcon } from '@/components';
 import React from 'react';
 
@@ -236,8 +242,21 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
       // content: initialState?.currentUser?.name,
     },
     itemRender: (route, _, routes) => {
-      const chilck = routes.indexOf(route) > 1;
-      return chilck && route.path !== '/iot/rule-engine/Alarm' ? (
+      console.log(route);
+      const isToParentUrl = getMenuPathByCode('notice');
+      const chilck = routes.indexOf(route) !== 0;
+      const goto = routes.some((item) => {
+        if (!route.path.includes('iot')) {
+          return routes.indexOf(route) <= 1;
+        } else {
+          if (route.path.includes('notice')) {
+            return item.path.indexOf(isToParentUrl) > -1;
+          } else {
+            return routes.indexOf(route) > 1;
+          }
+        }
+      });
+      return chilck && goto && route.path !== '/iot/rule-engine/Alarm' ? (
         <Link to={route.path}>{route.breadcrumbName}</Link>
       ) : (
         <span>{route.breadcrumbName}</span>

+ 2 - 1
src/components/Authorization/index.tsx

@@ -11,6 +11,7 @@ import _ from 'lodash';
 import { AuthorizationModel } from '@/components/Authorization/autz';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import DB from '@/db';
+import { onlyMessage } from '@/utils/util';
 
 const service = new Service();
 
@@ -182,7 +183,7 @@ const Authorization = observer((props: AuthorizationProps) => {
         permissionList: permissions,
       })
       .subscribe(async () => {
-        await message.success('授权成功');
+        await onlyMessage('授权成功');
       });
   };
 

+ 3 - 2
src/components/BaseCrud/save/index.tsx

@@ -1,5 +1,5 @@
 import React, { useEffect, useMemo, useState } from 'react';
-import { message, Modal, Spin } from 'antd';
+import { Modal, Spin } from 'antd';
 import {
   ArrayItems,
   ArrayTable,
@@ -34,6 +34,7 @@ import FUpload from '@/components/Upload';
 import FileUpload from '@/pages/link/Protocol/FileUpload';
 import FMonacoEditor from '@/components/FMonacoEditor';
 import FBraftEditor from '@/components/FBraftEditor';
+import { onlyMessage } from '@/utils/util';
 
 interface Props<T> {
   schema: ISchema;
@@ -111,7 +112,7 @@ const Save = <T extends Record<string, any>>(props: Props<T>) => {
     if (response.status === 200) {
       Store.set(SystemConst.BASE_UPDATE_DATA, response.result);
     }
-    message.success(
+    onlyMessage(
       intl.formatMessage({
         id: 'pages.data.option.success',
         defaultMessage: '操作成功',

+ 2 - 1
src/components/BindUser/Bound.tsx

@@ -9,6 +9,7 @@ import { observer } from '@formily/react';
 import { BindModel } from '@/components/BindUser/model';
 import { columns, service } from '@/components/BindUser/index';
 import { useIntl } from '@@/plugin-locale/localeExports';
+import { onlyMessage } from '@/utils/util';
 
 const Bound = observer(() => {
   const intl = useIntl();
@@ -23,7 +24,7 @@ const Bound = observer(() => {
 
   const handleUnBindResult = {
     next: async () => {
-      message.success(
+      onlyMessage(
         intl.formatMessage({
           id: 'pages.bindUser.theBoundUser.success',
           defaultMessage: '解绑成功',

+ 1 - 1
src/components/DashBoard/timePicker.tsx

@@ -1,7 +1,7 @@
 import type { DatePickerProps } from 'antd';
 import { DatePicker, Radio } from 'antd';
 import moment from 'moment';
-import { useEffect, useState, forwardRef, useImperativeHandle } from 'react';
+import { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
 
 export enum TimeKey {
   'today' = 'today',

+ 5 - 3
src/components/Player/ScreenPlayer.tsx

@@ -1,7 +1,7 @@
 import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
 import classNames from 'classnames';
 import LivePlayer from './index';
-import { Button, Dropdown, Empty, Menu, message, Popconfirm, Popover, Radio, Tooltip } from 'antd';
+import { Button, Dropdown, Empty, Menu, Popconfirm, Popover, Radio, Tooltip } from 'antd';
 import { createSchemaField } from '@formily/react';
 import { Form, FormItem, Input } from '@formily/antd';
 import { useFullscreen } from 'ahooks';
@@ -10,6 +10,7 @@ import { DeleteOutlined, QuestionCircleOutlined } from '@ant-design/icons';
 import Service from './service';
 import MediaTool from '@/components/Player/mediaTool';
 import { createForm } from '@formily/core';
+import { onlyMessage } from '@/utils/util';
 
 type Player = {
   id?: string;
@@ -196,9 +197,10 @@ export default forwardRef((props: ScreenProps, ref) => {
     if (resp.status === 200) {
       setVisible(false);
       getHistory();
-      message.success('保存成功!');
+      onlyMessage('保存成功!');
     } else {
-      message.error('保存失败');
+      onlyMessage('保存失败', 'error');
+      // message.error('保存失败');
     }
   }, [players, screen, historyForm]);
 

+ 1 - 1
src/components/ProTableCard/CardItems/noticeTemplate.tsx

@@ -16,7 +16,7 @@ export const imgMap = {
     dingTalkRobotWebHook: require('/public/images/notice/dingTalk-rebot.png'),
   },
   weixin: {
-    corpMessage: require('/public/images/notice/wechat.png'),
+    corpMessage: require('/public/images/notice/weixin-corp.png'),
     officialMessage: require('/public/images/notice/weixin-official.png'),
   },
   email: {

+ 5 - 5
src/components/SearchComponent/index.tsx

@@ -24,7 +24,7 @@ import {
   SaveOutlined,
   SearchOutlined,
 } from '@ant-design/icons';
-import { Button, Card, Dropdown, Empty, Menu, message, Popover, Typography } from 'antd';
+import { Button, Card, Dropdown, Empty, Menu, Popover, Typography } from 'antd';
 import { useEffect, useMemo, useRef, useState } from 'react';
 import type { ProColumns } from '@jetlinks/pro-table';
 import type { EnumData } from '@/utils/typings';
@@ -33,7 +33,7 @@ import Service from '@/components/SearchComponent/service';
 import _ from 'lodash';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import classnames from 'classnames';
-import { randomString } from '@/utils/util';
+import { onlyMessage, randomString } from '@/utils/util';
 
 const ui2Server = (source: SearchTermsUI): SearchTermsServer => [
   { terms: source.terms1 },
@@ -454,7 +454,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
                   e?.stopPropagation();
                   const response = await service.history.remove(`${target}-search`, item.key);
                   if (response.status === 200) {
-                    message.success('操作成功');
+                    onlyMessage('操作成功');
                     const temp = history.filter((h: any) => h.key !== item.key);
                     setHistory(temp);
                   }
@@ -530,9 +530,9 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
       content: JSON.stringify(value),
     });
     if (response.status === 200) {
-      message.success('保存成功!');
+      onlyMessage('保存成功!');
     } else {
-      message.error('保存失败');
+      onlyMessage('保存失败', 'error');
     }
     setAliasVisible(!aliasVisible);
   };

+ 12 - 0
src/global.less

@@ -115,3 +115,15 @@ ol {
     background-color: @primary-1;
   }
 }
+
+.ellipsis {
+  width: 100%;
+  overflow: hidden;
+  white-space: nowrap;
+  text-align: left;
+  text-overflow: ellipsis;
+}
+
+.ellipsis-70 {
+  width: 70%;
+}

+ 3 - 3
src/pages/Northbound/AliCloud/Detail/index.tsx

@@ -14,10 +14,10 @@ import type { Field } from '@formily/core';
 import { onFormInit } from '@formily/core';
 import { createForm, FormPath, onFieldChange, onFieldValueChange } from '@formily/core';
 import { createSchemaField, observer } from '@formily/react';
-import { Card, Col, Image, message, Row } from 'antd';
+import { Card, Col, Image, Row } from 'antd';
 import { useMemo } from 'react';
 import { useParams } from 'umi';
-import { useAsyncDataSource } from '@/utils/util';
+import { onlyMessage, useAsyncDataSource } from '@/utils/util';
 import './index.less';
 import { service } from '@/pages/Northbound/AliCloud';
 import usePermissions from '@/hooks/permission';
@@ -406,7 +406,7 @@ const Detail = observer(() => {
     data.bridgeProductName = product?.label || '';
     const response: any = data.id ? await service.update(data) : await service.save(data);
     if (response.status === 200) {
-      message.success('保存成功');
+      onlyMessage('保存成功');
       history.back();
     }
   };

+ 15 - 11
src/pages/Northbound/AliCloud/index.tsx

@@ -7,7 +7,7 @@ import { PermissionButton, ProTableCard } from '@/components';
 import {
   DeleteOutlined,
   EditOutlined,
-  ExclamationCircleFilled,
+  InfoCircleOutlined,
   PlayCircleOutlined,
   PlusOutlined,
   StopOutlined,
@@ -16,7 +16,8 @@ import { useIntl } from '@@/plugin-locale/localeExports';
 import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import AliyunCard from '@/components/ProTableCard/CardItems/aliyun';
 import Service from './service';
-import { Badge, message } from 'antd';
+import { Badge } from 'antd';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('device/aliyun/bridge');
 
@@ -74,10 +75,10 @@ const AliCloud = () => {
                 ? await service._disable(record.id)
                 : await service._enable(record.id);
             if (resp.status === 200) {
-              message.success('操作成功!');
+              onlyMessage('操作成功!');
               actionRef.current?.reload?.();
             } else {
-              message.error('操作失败!');
+              onlyMessage('操作失败!', 'error');
             }
           },
         }}
@@ -102,7 +103,7 @@ const AliCloud = () => {
           onConfirm: async () => {
             if (record?.state?.value === 'disabled') {
               await service.remove(record.id);
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',
@@ -110,7 +111,7 @@ const AliCloud = () => {
               );
               actionRef.current?.reload();
             } else {
-              message.error(intl.formatMessage({ id: 'pages.device.instance.deleteTip' }));
+              onlyMessage(intl.formatMessage({ id: 'pages.device.instance.deleteTip' }), 'error');
             }
           },
         }}
@@ -196,7 +197,7 @@ const AliCloud = () => {
             backgroundColor: '#f6f6f6',
           }}
         >
-          <ExclamationCircleFilled style={{ marginRight: 10 }} />
+          <InfoCircleOutlined style={{ marginRight: 10 }} />
           将平台产品与设备数据通过API的方式同步到阿里云物联网平台
         </div>
       </div>
@@ -278,10 +279,10 @@ const AliCloud = () => {
                         ? await service._disable(record.id)
                         : await service._enable(record.id);
                     if (resp.status === 200) {
-                      message.success('操作成功!');
+                      onlyMessage('操作成功!');
                       actionRef.current?.reload?.();
                     } else {
-                      message.error('操作失败!');
+                      onlyMessage('操作失败!', 'error');
                     }
                   },
                 }}
@@ -313,7 +314,7 @@ const AliCloud = () => {
                   onConfirm: async () => {
                     if (record?.state?.value === 'disabled') {
                       await service.remove(record.id);
-                      message.success(
+                      onlyMessage(
                         intl.formatMessage({
                           id: 'pages.data.option.success',
                           defaultMessage: '操作成功!',
@@ -321,7 +322,10 @@ const AliCloud = () => {
                       );
                       actionRef.current?.reload();
                     } else {
-                      message.error(intl.formatMessage({ id: 'pages.device.instance.deleteTip' }));
+                      onlyMessage(
+                        intl.formatMessage({ id: 'pages.device.instance.deleteTip' }),
+                        'error',
+                      );
                     }
                   },
                 }}

+ 5 - 1
src/pages/Northbound/DuerOS/Detail/Doc.tsx

@@ -7,7 +7,11 @@ const Doc = () => {
     <div className="doc">
       <div className="url">
         小度智能家居开放平台:
-        <a href="https://dueros.baidu.com/dbp/bot/index#/iotopenplatform">
+        <a
+          href="https://dueros.baidu.com/dbp/bot/index#/iotopenplatform"
+          target="_blank"
+          rel="noopener noreferrer"
+        >
           https://dueros.baidu.com/dbp/bot/index#/iotopenplatform
         </a>
       </div>

+ 4 - 4
src/pages/Northbound/DuerOS/Detail/index.tsx

@@ -1,7 +1,7 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import { createSchemaField } from '@formily/react';
 import { ISchema } from '@formily/json-schema';
-import { Card, Col, message, Row } from 'antd';
+import { Card, Col, Row } from 'antd';
 import {
   ArrayCollapse,
   ArrayTable,
@@ -23,7 +23,7 @@ import {
   onFieldValueChange,
   onFormInit,
 } from '@formily/core';
-import { useAsyncDataSource } from '@/utils/util';
+import { onlyMessage, useAsyncDataSource } from '@/utils/util';
 import { service } from '..';
 import { Store } from 'jetlinks-store';
 import { useParams } from 'umi';
@@ -600,9 +600,9 @@ const Save = () => {
     const productName = Store.get('product-list')?.find((item: any) => item.id === data.id)?.name;
     const resp: any = await service.savePatch({ ...data, productName });
     if (resp.status === 200) {
-      message.success('保存成功!');
+      onlyMessage('保存成功!');
     } else {
-      message.error('保存失败!');
+      onlyMessage('保存失败!', 'error');
     }
     history.back();
   };

+ 7 - 6
src/pages/Northbound/DuerOS/index.tsx

@@ -7,17 +7,18 @@ import {
   CloseCircleOutlined,
   DeleteOutlined,
   EditOutlined,
-  ExclamationCircleFilled,
+  InfoCircleOutlined,
   PlayCircleOutlined,
   PlusOutlined,
 } from '@ant-design/icons';
 import { useIntl } from '@@/plugin-locale/localeExports';
-import { Badge, message, Space } from 'antd';
+import { Badge, Space } from 'antd';
 import { DuerOSItem } from '@/pages/Northbound/DuerOS/types';
 import DuerOSCard from '@/components/ProTableCard/CardItems/duerOs';
 import { history } from '@@/core/history';
 import { getMenuPathByCode, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import Service from './service';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('dueros/product');
 export default () => {
@@ -73,14 +74,14 @@ export default () => {
             };
             const resp = await service.changeState(record.id, map[record.state?.value]);
             if (resp.status === 200) {
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',
                 }),
               );
             } else {
-              message.error('操作失败!');
+              onlyMessage('操作失败!', 'error');
             }
 
             actionRef.current?.reload();
@@ -117,7 +118,7 @@ export default () => {
           title: '确认删除?',
           onConfirm: async () => {
             await service.remove(record.id);
-            message.success('删除成功!');
+            onlyMessage('删除成功!');
             actionRef.current?.reload();
           },
         }}
@@ -230,7 +231,7 @@ export default () => {
             backgroundColor: '#f6f6f6',
           }}
         >
-          <ExclamationCircleFilled style={{ marginRight: 10 }} />
+          <InfoCircleOutlined style={{ marginRight: 10 }} />
           将平台产品通过API的方式同步DuerOS平台
         </div>
       </div>

+ 6 - 0
src/pages/Northbound/DuerOS/service.ts

@@ -14,6 +14,12 @@ class Service extends BaseService<DuerOSItem> {
       method: 'POST',
       data: {
         paging: false,
+        terms: [
+          {
+            column: 'id$dueros-product$not',
+            value: 1,
+          },
+        ],
       },
     });
 

+ 6 - 5
src/pages/account/Center/bind/index.tsx

@@ -1,10 +1,11 @@
-import { Button, Card, message, Form, Input } from 'antd';
+import { Button, Card, Form, Input } from 'antd';
 import { useEffect, useState } from 'react';
 import Service from '@/pages/account/Center/service';
 import api from '@/pages/user/Login/service';
 import styles from './index.less';
 import Token from '@/utils/token';
 import { useModel } from '@@/plugin-model/useModel';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service();
 
@@ -85,11 +86,11 @@ const Bind = () => {
         Token.set(userInfo.token);
         await fetchUserInfo();
         localStorage.setItem('onLogin', 'yes');
-        message.success('登录成功');
+        onlyMessage('登录成功');
         setTimeout(() => window.close(), 1000);
       },
       error: () => {
-        message.error('登录失败,请重试!');
+        onlyMessage('登录失败,请重试', 'error');
       },
     });
   };
@@ -193,11 +194,11 @@ const Bind = () => {
                 onClick={() => {
                   service.bind(code).then((res) => {
                     if (res.status === 200) {
-                      message.success('绑定成功');
+                      onlyMessage('绑定成功');
                       localStorage.setItem('onBind', 'true');
                       setTimeout(() => window.close(), 1000);
                     } else {
-                      message.error('绑定失败');
+                      onlyMessage('绑定失败', 'error');
                     }
                   });
                 }}

+ 6 - 5
src/pages/account/Center/index.tsx

@@ -24,6 +24,7 @@ import moment from 'moment';
 import { useModel } from 'umi';
 import usePermissions from '@/hooks/permission';
 import { PermissionButton } from '@/components';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service();
 
@@ -79,7 +80,7 @@ const Center = () => {
             if (res.status === 200) {
               setImageUrl(info.file.response.result);
               getDetail();
-              message.success('上传成功');
+              onlyMessage('上传成功');
             }
           });
         // setLoading(false);
@@ -90,18 +91,18 @@ const Center = () => {
   const saveInfo = (parms: UserDetail) => {
     service.saveUserDetail(parms).subscribe((res) => {
       if (res.status === 200) {
-        message.success('保存成功');
+        onlyMessage('保存成功');
         getDetail();
         setInfos(false);
       } else {
-        message.success('保存失败');
+        onlyMessage('保存失败', 'error');
       }
     });
   };
   const savePassword = (parms: { oldPassword: string; newPassword: string }) => {
     service.savePassWord(parms).subscribe((res) => {
       if (res.status === 200) {
-        message.success('保存成功');
+        onlyMessage('保存成功');
       }
     });
   };
@@ -115,7 +116,7 @@ const Center = () => {
   const unBind = (type: string, provider: string) => {
     service.unbind(type, provider).then((res) => {
       if (res.status === 200) {
-        message.success('解绑成功');
+        onlyMessage('解绑成功');
         getBindInfo();
       }
     });

+ 3 - 2
src/pages/account/NotificationRecord/index.tsx

@@ -7,10 +7,11 @@ import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
 import { useEffect, useRef, useState } from 'react';
 import Detail from './detail';
-import { Badge, message } from 'antd';
+import { Badge } from 'antd';
 import Service from './service';
 import encodeQuery from '@/utils/encodeQuery';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('notifications');
 
@@ -105,7 +106,7 @@ const NotificationRecord = () => {
               const state = record?.state?.value !== 'read' ? 'read' : 'unread';
               const resp = await service.saveData(state, [record.id]);
               if (resp.status === 200) {
-                message.success('操作成功');
+                onlyMessage('操作成功');
                 actionRef.current?.reload();
               }
             },

+ 6 - 5
src/pages/account/NotificationSubscription/index.tsx

@@ -12,11 +12,12 @@ import { PageContainer } from '@ant-design/pro-layout';
 import { observer } from '@formily/reactive-react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
-import { Badge, message } from 'antd';
+import { Badge } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 import Save from './save';
 import Service from './service';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('notifications/subscriptions');
 
@@ -77,10 +78,10 @@ const NotificationSubscription = observer(() => {
                 ? await service._disabled(record.id)
                 : await service._enabled(record.id);
             if (resp.status === 200) {
-              message.success('操作成功!');
+              onlyMessage('操作成功!');
               actionRef.current?.reload?.();
             } else {
-              message.error('操作失败!');
+              onlyMessage('操作失败!', 'error');
             }
           },
         }}
@@ -105,10 +106,10 @@ const NotificationSubscription = observer(() => {
           onConfirm: async () => {
             const resp: any = await service.remove(record.id);
             if (resp.status === 200) {
-              message.success('操作成功!');
+              onlyMessage('操作成功!');
               actionRef.current?.reload?.();
             } else {
-              message.error('操作失败!');
+              onlyMessage('操作失败!', 'error');
             }
           },
         }}

+ 3 - 3
src/pages/account/NotificationSubscription/save/index.tsx

@@ -1,10 +1,10 @@
-import { message, Modal } from 'antd';
+import { Modal } from 'antd';
 import { useEffect, useMemo, useState } from 'react';
 import { Checkbox, Form, FormGrid, FormItem, Input, Select } from '@formily/antd';
 import { createForm } from '@formily/core';
 import type { ISchema } from '@formily/react';
 import { createSchemaField } from '@formily/react';
-import { useAsyncDataSource } from '@/utils/util';
+import { onlyMessage, useAsyncDataSource } from '@/utils/util';
 import { service } from '@/pages/account/NotificationSubscription';
 import _ from 'lodash';
 
@@ -198,7 +198,7 @@ const Save = (props: Props) => {
     };
     const response: any = await service.saveData(param);
     if (response.status === 200) {
-      message.success('操作成功!');
+      onlyMessage('操作成功!');
       props.reload();
     }
   };

+ 3 - 2
src/pages/cloud/Aliyun/index.tsx

@@ -3,7 +3,7 @@ import BaseService from '@/utils/BaseService';
 import { useRef } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import BaseCrud from '@/components/BaseCrud';
-import { message, Popconfirm, Tooltip } from 'antd';
+import { Popconfirm, Tooltip } from 'antd';
 import {
   CloseCircleOutlined,
   EditOutlined,
@@ -13,6 +13,7 @@ import {
 import { CurdModel } from '@/components/BaseCrud/model';
 import type { AliyunItem } from '@/pages/cloud/Aliyun/typings';
 import { useIntl } from '@@/plugin-locale/localeExports';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new BaseService<AliyunItem>('device/aliyun/bridge');
 
@@ -95,7 +96,7 @@ const Aliyun = () => {
             onConfirm={async () => {
               // const state = record.state.value === 'disabled' ? 'enable' : 'disable';
               // await service.changeStatus(record.id, state);
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',

+ 3 - 2
src/pages/cloud/Ctwing/index.tsx

@@ -4,10 +4,11 @@ import BaseService from '@/utils/BaseService';
 import { CloseCircleOutlined, EditOutlined, PlayCircleOutlined } from '@ant-design/icons';
 import { PageContainer } from '@ant-design/pro-layout';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { message, Popconfirm, Tooltip } from 'antd';
+import { Popconfirm, Tooltip } from 'antd';
 import { useRef } from 'react';
 import type { CtwingItem } from '@/pages/cloud/Ctwing/typings';
 import { useIntl } from '@@/plugin-locale/localeExports';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new BaseService<CtwingItem>('ctwing/product');
 
@@ -79,7 +80,7 @@ const Ctwing = () => {
             onConfirm={async () => {
               // const state = record.state.value === 'disabled' ? 'enable' : 'disable';
               // await service.changeStatus(record.id, state);
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',

+ 3 - 2
src/pages/cloud/Onenet/index.tsx

@@ -2,7 +2,7 @@ import { PageContainer } from '@ant-design/pro-layout';
 import BaseService from '@/utils/BaseService';
 import { useRef } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { message, Popconfirm, Tooltip } from 'antd';
+import { Popconfirm, Tooltip } from 'antd';
 import {
   CloseCircleOutlined,
   EditOutlined,
@@ -13,6 +13,7 @@ import BaseCrud from '@/components/BaseCrud';
 import { CurdModel } from '@/components/BaseCrud/model';
 import type { OnenetItem } from '@/pages/cloud/Onenet/typings';
 import { useIntl } from '@@/plugin-locale/localeExports';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new BaseService<OnenetItem>('one-net/product');
 
@@ -82,7 +83,7 @@ const Onenet = () => {
               defaultMessage: `确认${record.state.value === 'disabled' ? '启' : '禁'}用?`,
             })}
             onConfirm={async () => {
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',

+ 4 - 3
src/pages/device/Alarm/index.tsx

@@ -3,12 +3,13 @@ import BaseService from '@/utils/BaseService';
 import { useRef } from 'react';
 import type { ProColumns, ActionType } from '@jetlinks/pro-table';
 import moment from 'moment';
-import { Form, Input, message, Modal, Tag, Tooltip } from 'antd';
+import { Form, Input, Modal, Tag, Tooltip } from 'antd';
 import { CheckOutlined, EyeOutlined } from '@ant-design/icons';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import ProTable from '@jetlinks/pro-table';
 import { request } from 'umi';
 import SystemConst from '@/utils/const';
+import { onlyMessage } from '@/utils/util';
 
 const service = new BaseService<AlarmItem>('device/alarm/history');
 const Alarm = () => {
@@ -142,9 +143,9 @@ const Alarm = () => {
                       },
                     );
                     if (resp.status === 200) {
-                      message.success('操作成功');
+                      onlyMessage('操作成功');
                     } else {
-                      message.error('操作失败');
+                      onlyMessage('操作失败', 'error');
                     }
                     actionRef.current?.reload();
                   },

+ 4 - 3
src/pages/device/Category/Save/index.tsx

@@ -17,12 +17,13 @@ import { createForm } from '@formily/core';
 import { createSchemaField } from '@formily/react';
 import FUpload from '@/components/Upload';
 import * as ICONS from '@ant-design/icons';
-import { message, Modal } from 'antd';
+import { Modal } from 'antd';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import type { ISchema } from '@formily/json-schema';
 import type { CategoryItem } from '@/pages/visualization/Category/typings';
 import { service, state } from '@/pages/device/Category';
 import type { Response } from '@/utils/typings';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   visible: boolean;
@@ -70,12 +71,12 @@ const Save = (props: Props) => {
       ? await service.update(value as CategoryItem)
       : ((await service.save(value as any)) as Response<CategoryItem>);
     if (resp.status === 200) {
-      message.success('操作成功!');
+      onlyMessage('操作成功');
       if (props.reload) {
         props.reload();
       }
     } else {
-      message.error('操作失败');
+      onlyMessage('操作失败', 'error');
     }
     props.close();
   };

+ 3 - 3
src/pages/device/Category/index.tsx

@@ -3,7 +3,6 @@ import Service from '@/pages/device/Category/service';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
 import { DeleteOutlined, EditOutlined, PlusCircleOutlined, PlusOutlined } from '@ant-design/icons';
-import { message } from 'antd';
 import { useRef, useState } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import Save from '@/pages/device/Category/Save';
@@ -13,6 +12,7 @@ import type { Response } from '@/utils/typings';
 import SearchComponent from '@/components/SearchComponent';
 import { PermissionButton } from '@/components';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('device/category');
 
@@ -146,9 +146,9 @@ const Category = observer(() => {
             onConfirm: async () => {
               const resp = (await service.remove(record.id)) as Response<any>;
               if (resp.status === 200) {
-                message.success('操作成功');
+                onlyMessage('操作成功');
               } else {
-                message.error('操作失败');
+                onlyMessage('操作失败', 'error');
               }
               actionRef.current?.reload();
             },

+ 4 - 3
src/pages/device/Command/create/index.tsx

@@ -5,10 +5,11 @@ import { ArrayTable, Form, FormItem, Input, Select, Space } from '@formily/antd'
 import { action } from '@formily/reactive';
 import type { ISchema } from '@formily/json-schema';
 import { service } from '@/pages/device/Command';
-import { message, Modal } from 'antd';
+import { Modal } from 'antd';
 import FSelectDevices from '@/components/FSelectDevices';
 import { useRef } from 'react';
 import type { DeviceMetadata, ProductItem } from '@/pages/device/Product/typings';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   close: () => void;
@@ -235,9 +236,9 @@ const Create = (props: Props) => {
     }
     const resp = await service.task(values);
     if (resp.status === 200) {
-      message.success('操作成功');
+      onlyMessage('操作成功');
     } else {
-      message.error('操作失败');
+      onlyMessage('操作失败', 'error');
     }
     close();
   };

+ 4 - 3
src/pages/device/Command/index.tsx

@@ -2,7 +2,7 @@ import { PageContainer } from '@ant-design/pro-layout';
 import { useRef } from 'react';
 import type { ProColumns, ActionType } from '@jetlinks/pro-table';
 import type { CommandItem } from '@/pages/device/Command/typings';
-import { Button, message, Tooltip } from 'antd';
+import { Button, Tooltip } from 'antd';
 import moment from 'moment';
 import { EyeOutlined, PlusOutlined, SyncOutlined } from '@ant-design/icons';
 import { useIntl } from '@@/plugin-locale/localeExports';
@@ -13,6 +13,7 @@ import encodeQuery from '@/utils/encodeQuery';
 import { model } from '@formily/reactive';
 import { observer } from '@formily/react';
 import Cat from '@/pages/device/Command/cat';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('device/message/task');
 
@@ -158,9 +159,9 @@ const Command = observer(() => {
             onClick={async () => {
               const resp = await service.resend(encodeQuery({ terms: { id: record.id } }));
               if (resp.status === 200) {
-                message.success('操作成功!');
+                onlyMessage('操作成功!');
               } else {
-                message.error('操作失败!');
+                onlyMessage('操作失败!', 'error');
               }
             }}
           >

+ 4 - 3
src/pages/device/Firmware/Detail/Task/Release/index.tsx

@@ -1,4 +1,4 @@
-import { message, Modal } from 'antd';
+import { Modal } from 'antd';
 import { createForm } from '@formily/core';
 import { createSchemaField } from '@formily/react';
 import { Form, FormItem, Select } from '@formily/antd';
@@ -6,6 +6,7 @@ import type { ISchema } from '@formily/json-schema';
 import FSelectDevices from '@/components/FSelectDevices';
 import { service, state } from '@/pages/device/Firmware';
 import type { DeviceInstance } from '@/pages/device/Instance/typings';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   close: () => void;
@@ -36,9 +37,9 @@ const Release = (props: Props) => {
       values?.part?.map((i) => i.id),
     );
     if (resp.status === 200) {
-      message.success('操作成功');
+      onlyMessage('操作成功');
     } else {
-      message.error('操作失败');
+      onlyMessage('操作失败', 'error');
     }
     props.close();
   };

+ 4 - 3
src/pages/device/Firmware/Detail/Task/Save/index.tsx

@@ -1,9 +1,10 @@
-import { message, Modal } from 'antd';
+import { Modal } from 'antd';
 import { service, state } from '../../..';
 import { createForm } from '@formily/core';
 import { createSchemaField } from '@formily/react';
 import { Form, FormItem, Input, NumberPicker, Select } from '@formily/antd';
 import type { ISchema } from '@formily/json-schema';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   visible: boolean;
@@ -61,9 +62,9 @@ const Save = (props: Props) => {
     values.firmwareId = state.current?.id;
     const resp = await service.saveTask(values);
     if (resp.status === 200) {
-      message.success('操作成功');
+      onlyMessage('操作成功');
     } else {
-      message.error('操作失败');
+      onlyMessage('操作失败', 'error');
     }
     props.close();
   };

+ 4 - 3
src/pages/device/Firmware/Save/index.tsx

@@ -1,4 +1,4 @@
-import { message, Modal } from 'antd';
+import { Modal } from 'antd';
 import type { FirmwareItem } from '@/pages/device/Firmware/typings';
 import { createSchemaField } from '@formily/react';
 import { Form, FormGrid, FormItem, Input, Select } from '@formily/antd';
@@ -11,6 +11,7 @@ import { service } from '@/pages/device/Firmware';
 import type { Response } from '@/utils/typings';
 import { useRef } from 'react';
 import type { ProductItem } from '@/pages/device/Product/typings';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   data?: FirmwareItem;
@@ -54,9 +55,9 @@ const Save = (props: Props) => {
     values.productName = product?.name || '';
     const resp = (await service.save(values)) as Response<FirmwareItem>;
     if (resp.status === 200) {
-      message.success('保存成功!');
+      onlyMessage('保存成功!');
     } else {
-      message.error('保存失败!');
+      onlyMessage('保存失败!', 'error');
     }
   };
   const schema: ISchema = {

+ 3 - 2
src/pages/device/Firmware/index.tsx

@@ -1,6 +1,6 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import type { ProColumns, ActionType } from '@jetlinks/pro-table';
-import { Button, message, Popconfirm, Tooltip } from 'antd';
+import { Button, Popconfirm, Tooltip } from 'antd';
 import moment from 'moment';
 import { useRef } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
@@ -12,6 +12,7 @@ import { observer } from '@formily/react';
 import type { FirmwareItem, TaskItem } from '@/pages/device/Firmware/typings';
 import Service from '@/pages/device/Firmware/service';
 import Save from '@/pages/device/Firmware/Save';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('firmware');
 
@@ -131,7 +132,7 @@ const Firmware = observer(() => {
             })}
             onConfirm={async () => {
               await service.remove(record.id);
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',

+ 4 - 3
src/pages/device/Instance/Detail/ChildDevice/index.tsx

@@ -1,7 +1,7 @@
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
 import type { LogItem } from '@/pages/device/Instance/Detail/Log/typings';
-import { Badge, Button, Card, message, Popconfirm, Tooltip } from 'antd';
+import { Badge, Button, Card, Popconfirm, Tooltip } from 'antd';
 import { DisconnectOutlined, SearchOutlined } from '@ant-design/icons';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { InstanceModel, service, statusMap } from '@/pages/device/Instance';
@@ -12,6 +12,7 @@ import moment from 'moment';
 import { Link } from 'umi';
 import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 const ChildDevice = () => {
   const intl = useIntl();
@@ -27,7 +28,7 @@ const ChildDevice = () => {
     const resp = await service.unbindDevice(InstanceModel.detail.id!, id, {});
     if (resp.status === 200) {
       actionRef.current?.reset?.();
-      message.success('操作成功!');
+      onlyMessage('操作成功!');
     }
   };
 
@@ -173,7 +174,7 @@ const ChildDevice = () => {
             onConfirm={async () => {
               const resp = await service.unbindBatchDevice(InstanceModel.detail.id!, bindKeys);
               if (resp.status === 200) {
-                message.success('操作成功!');
+                onlyMessage('操作成功!');
                 setBindKeys([]);
                 actionRef.current?.reset?.();
               }

+ 3 - 2
src/pages/device/Instance/Detail/Config/Edit.tsx

@@ -3,8 +3,9 @@ import { createSchemaField } from '@formily/react';
 import { InstanceModel, service } from '@/pages/device/Instance';
 import type { ISchema } from '@formily/json-schema';
 import { Form, FormGrid, FormItem, Input, Password, PreviewText } from '@formily/antd';
-import { Button, Drawer, message, Space } from 'antd';
+import { Button, Drawer, Space } from 'antd';
 import { useParams } from 'umi';
+import { onlyMessage } from '@/utils/util';
 
 const componentMap = {
   string: 'Input',
@@ -100,7 +101,7 @@ const Edit = (props: Props) => {
                 configuration: { ...values },
               });
               if (resp.status === 200) {
-                message.success('操作成功!');
+                onlyMessage('操作成功!');
                 if ((window as any).onTabSaveSuccess) {
                   if (resp.result) {
                     (window as any).onTabSaveSuccess(resp);

+ 4 - 3
src/pages/device/Instance/Detail/Config/index.tsx

@@ -1,4 +1,4 @@
-import { Descriptions, message, Space, Tooltip } from 'antd';
+import { Descriptions, Space, Tooltip } from 'antd';
 import { InstanceModel, service } from '@/pages/device/Instance';
 import { useEffect, useState } from 'react';
 import type { ConfigMetadata } from '@/pages/device/Product/typings';
@@ -11,6 +11,7 @@ import {
 } from '@ant-design/icons';
 import Edit from './Edit';
 import { PermissionButton } from '@/components';
+import { onlyMessage } from '@/utils/util';
 
 const Config = () => {
   const params = useParams<{ id: string }>();
@@ -99,7 +100,7 @@ const Config = () => {
                 onConfirm: async () => {
                   const resp = await service.deployDevice(id || '');
                   if (resp.status === 200) {
-                    message.success('操作成功');
+                    onlyMessage('操作成功');
                     getDetail();
                   }
                 },
@@ -121,7 +122,7 @@ const Config = () => {
                 onConfirm: async () => {
                   const resp = await service.configurationReset(id || '');
                   if (resp.status === 200) {
-                    message.success('恢复默认配置成功');
+                    onlyMessage('恢复默认配置成功');
                     getDetail();
                   }
                 },

+ 2 - 2
src/pages/device/Instance/Detail/Diagnose/Status/DiagnosticAdvice.tsx

@@ -1,5 +1,5 @@
 import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
-import { ExclamationCircleFilled } from '@ant-design/icons';
+import { InfoCircleOutlined } from '@ant-design/icons';
 import { Badge, Modal } from 'antd';
 import styles from './index.less';
 
@@ -42,7 +42,7 @@ const DiagnosticAdvice = (props: Props) => {
     >
       <div className={styles.advice}>
         <div className={styles.alert}>
-          <ExclamationCircleFilled style={{ marginRight: 10 }} />
+          <InfoCircleOutlined style={{ marginRight: 10 }} />
           所有诊断均无异常但设备任未上线,请检查以下内容
         </div>
         {(data?.product || []).map((item: any) => (

+ 2 - 2
src/pages/device/Instance/Detail/Diagnose/Status/ManualInspection.tsx

@@ -4,7 +4,7 @@ import type { ISchema } from '@formily/json-schema';
 import { Form, FormGrid, FormItem, Input, Password, PreviewText } from '@formily/antd';
 import { Modal } from 'antd';
 import styles from './index.less';
-import { ExclamationCircleFilled } from '@ant-design/icons';
+import { InfoCircleOutlined } from '@ant-design/icons';
 
 const componentMap = {
   string: 'Input',
@@ -132,7 +132,7 @@ const ManualInspection = (props: Props) => {
       visible
     >
       <div className={styles.alert}>
-        <ExclamationCircleFilled style={{ marginRight: 10 }} />
+        <InfoCircleOutlined style={{ marginRight: 10 }} />
         {data.type === 'product'
           ? `当前填写的数据将与产品-设备接入配置中的${data.data.name}数据进行比对`
           : `当前填写的数据将与设备-实例信息配置中的${data.data.name}数据进行比对`}

+ 6 - 5
src/pages/device/Instance/Detail/Diagnose/Status/index.tsx

@@ -1,5 +1,5 @@
 import TitleComponent from '@/components/TitleComponent';
-import { Badge, Button, Col, message, Popconfirm, Row } from 'antd';
+import { Badge, Button, Col, Popconfirm, Row } from 'antd';
 import { useEffect, useState } from 'react';
 import styles from './index.less';
 import { InstanceModel, service } from '@/pages/device/Instance';
@@ -10,6 +10,7 @@ import { DiagnoseStatusModel } from './model';
 import { PermissionButton } from '@/components';
 import DiagnosticAdvice from './DiagnosticAdvice';
 import ManualInspection from './ManualInspection';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   onChange: (type: string) => void;
@@ -215,7 +216,7 @@ const Status = observer((props: Props) => {
                                             DiagnoseStatusModel.gateway?.channelId,
                                           );
                                           if (res.status === 200) {
-                                            message.success('操作成功!');
+                                            onlyMessage('操作成功!');
                                             DiagnoseStatusModel.status.network = {
                                               status: 'success',
                                               text: '正常',
@@ -335,7 +336,7 @@ const Status = observer((props: Props) => {
                               InstanceModel.detail?.productId || '',
                             );
                             if (resp.status === 200) {
-                              message.success('操作成功!');
+                              onlyMessage('操作成功!');
                               DiagnoseStatusModel.status.product = {
                                 status: 'success',
                                 text: '正常',
@@ -389,7 +390,7 @@ const Status = observer((props: Props) => {
                         onConfirm={async () => {
                           const resp = await service.deployDevice(InstanceModel.detail?.id || '');
                           if (resp.status === 200) {
-                            message.success('操作成功!');
+                            onlyMessage('操作成功!');
                             DiagnoseStatusModel.status.device = {
                               status: 'success',
                               text: '正常',
@@ -567,7 +568,7 @@ const Status = observer((props: Props) => {
                           onConfirm={async () => {
                             const resp = await service.startGateway(gateway?.id || '');
                             if (resp.status === 200) {
-                              message.success('操作成功!');
+                              onlyMessage('操作成功!');
                               DiagnoseStatusModel.status.deviceAccess = {
                                 status: 'success',
                                 text: '正常',

+ 2 - 2
src/pages/device/Instance/Detail/Functions/AdvancedMode.tsx

@@ -1,6 +1,6 @@
 import type { FunctionMetadata } from '@/pages/device/Product/typings';
-import { useState, useEffect, useRef, useCallback } from 'react';
-import { Input, Button } from 'antd';
+import { useCallback, useEffect, useRef, useState } from 'react';
+import { Button, Input } from 'antd';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { InstanceModel, service } from '@/pages/device/Instance';
 import MonacoEditor from 'react-monaco-editor';

+ 3 - 2
src/pages/device/Instance/Detail/MetadataMap/EditableTable/index.tsx

@@ -1,8 +1,9 @@
 import React, { useContext, useEffect, useState } from 'react';
-import { Badge, Col, Form, Input, message, Pagination, Row, Select, Table, Tooltip } from 'antd';
+import { Badge, Col, Form, Input, Pagination, Row, Select, Table, Tooltip } from 'antd';
 import { service } from '@/pages/device/Instance';
 import './index.less';
 import { QuestionCircleOutlined } from '@ant-design/icons';
+import { onlyMessage } from '@/utils/util';
 // import { throttle } from 'lodash';
 
 const defaultImage = require('/public/images/metadata-map.png');
@@ -260,7 +261,7 @@ const EditableTable = (props: Props) => {
         },
       ]);
       if (resp.status === 200) {
-        message.success('操作成功!');
+        onlyMessage('操作成功!');
         // 刷新
         initData(protocolMetadata);
       }

+ 5 - 4
src/pages/device/Instance/Detail/Modbus/index.tsx

@@ -1,5 +1,5 @@
 import PermissionButton from '@/components/PermissionButton';
-import { Badge, Card, Empty, Input, message, Tabs, Tooltip } from 'antd';
+import { Badge, Card, Empty, Input, Tabs, Tooltip } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 import { useIntl } from 'umi';
 import styles from '@/pages/link/Channel/Opcua/Access/index.less';
@@ -18,6 +18,7 @@ import AddPoint from '@/pages/link/Channel/Modbus/Access/addPoint';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
 import { map } from 'rxjs/operators';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 const Modbus = () => {
   const intl = useIntl();
@@ -111,7 +112,7 @@ const Modbus = () => {
                 state: record.state.value === 'enabled' ? 'disabled' : 'enabled',
               };
               await service.saveMetadataConfig(opcId, deviceId, item);
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',
@@ -149,7 +150,7 @@ const Modbus = () => {
             onConfirm: async () => {
               const resp: any = await service.removeMetadataConfig(record.id);
               if (resp.status === 200) {
-                message.success(
+                onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
                     defaultMessage: '操作成功!',
@@ -315,7 +316,7 @@ const Modbus = () => {
                             const resp: any = await service.remove(item.id);
                             if (resp.status === 200) {
                               getModbus(deviceId);
-                              message.success(
+                              onlyMessage(
                                 intl.formatMessage({
                                   id: 'pages.data.option.success',
                                   defaultMessage: '操作成功!',

+ 5 - 4
src/pages/device/Instance/Detail/Opcua/index.tsx

@@ -1,5 +1,5 @@
 import PermissionButton from '@/components/PermissionButton';
-import { Badge, Card, Empty, Input, message, Tabs, Tooltip } from 'antd';
+import { Badge, Card, Empty, Input, Tabs, Tooltip } from 'antd';
 import { useEffect, useMemo, useRef, useState } from 'react';
 import { useIntl } from 'umi';
 import styles from '@/pages/link/Channel/Opcua/Access/index.less';
@@ -18,6 +18,7 @@ import AddPoint from '@/pages/link/Channel/Opcua/Access/addPoint';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
 import { map } from 'rxjs/operators';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 const Opcua = () => {
   const intl = useIntl();
@@ -115,7 +116,7 @@ const Opcua = () => {
               } else {
                 await service.stopPoint(record.deviceId, [record.id]);
               }
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',
@@ -153,7 +154,7 @@ const Opcua = () => {
             onConfirm: async () => {
               const resp: any = await service.deletePoint(record.id);
               if (resp.status === 200) {
-                message.success(
+                onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
                     defaultMessage: '操作成功!',
@@ -331,7 +332,7 @@ const Opcua = () => {
                               const resp: any = await service.remove(item.id);
                               if (resp.status === 200) {
                                 getOpc(deviceId);
-                                message.success(
+                                onlyMessage(
                                   intl.formatMessage({
                                     id: 'pages.data.option.success',
                                     defaultMessage: '操作成功!',

+ 3 - 2
src/pages/device/Instance/Detail/Reation/Edit.tsx

@@ -5,10 +5,11 @@ import { InstanceModel, service } from '@/pages/device/Instance';
 import type { ISchema } from '@formily/json-schema';
 import { Form, FormGrid, FormItem, PreviewText, Select } from '@formily/antd';
 import { useParams } from 'umi';
-import { Button, Drawer, message, Space } from 'antd';
+import { Button, Drawer, Space } from 'antd';
 import { action } from '@formily/reactive';
 import type { Response } from '@/utils/typings';
 import { useEffect, useMemo, useState } from 'react';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   close: () => void;
@@ -145,7 +146,7 @@ const Edit = (props: Props) => {
                 });
                 const resp = await service.saveRelations(id || '', param);
                 if (resp.status === 200) {
-                  message.success('操作成功!');
+                  onlyMessage('操作成功!');
                   props.close();
                   if (props.reload) {
                     props.reload();

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

@@ -1,4 +1,4 @@
-import { Alert, message, Modal } from 'antd';
+import { Alert, Modal } from 'antd';
 import { FormItem, Input } from '@formily/antd';
 import { createForm } from '@formily/core';
 import { createSchemaField, FormProvider } from '@formily/react';
@@ -39,7 +39,7 @@ const EditProperty = (props: Props) => {
   const handleSetPropertyValue = async (propertyValue: string) => {
     const resp = await service.setProperty(params.id, { [`${data.id}`]: propertyValue });
     if (resp.status === 200) {
-      message.success('操作成功');
+      onlyMessage('操作成功');
     }
     props.onCancel();
   };

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

@@ -1,4 +1,4 @@
-import { message, Modal } from 'antd';
+import { Modal } from 'antd';
 import {
   ArrayItems,
   Checkbox,
@@ -15,6 +15,7 @@ import { createSchemaField } from '@formily/react';
 import type { PropertyMetadata } from '@/pages/device/Product/typings';
 import { useEffect, useState } from 'react';
 import { InstanceModel, service } from '@/pages/device/Instance';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   data: Partial<PropertyMetadata>;
@@ -222,7 +223,7 @@ const Indicators = (props: Props) => {
         });
         const resp = await service.saveMetric(InstanceModel.detail.id || '', data.id || '', list);
         if (resp.status === 200) {
-          message.success('操作成功!');
+          onlyMessage('操作成功!');
           props.onCancel();
         }
       }}

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

@@ -4,7 +4,7 @@ import {
   SyncOutlined,
   UnorderedListOutlined,
 } from '@ant-design/icons';
-import { Card, message, Space, Spin, Tooltip } from 'antd';
+import { Card, Space, Spin, Tooltip } from 'antd';
 import type { PropertyMetadata } from '@/pages/device/Product/typings';
 import { useEffect, useState } from 'react';
 import { service } from '@/pages/device/Instance';
@@ -15,6 +15,7 @@ import moment from 'moment';
 import Indicators from './Indicators';
 import './PropertyCard.less';
 import FileComponent from './FileComponent';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   data: Partial<PropertyMetadata>;
@@ -33,7 +34,7 @@ const Property = (props: Props) => {
     const resp = await service.getProperty(params.id, data.id);
     setLoading(false);
     if (resp.status === 200) {
-      message.success('操作成功');
+      onlyMessage('操作成功');
     }
   };
 

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

@@ -1,4 +1,4 @@
-import { Col, Empty, Input, message, Pagination, Row, Space, Spin, Table } from 'antd';
+import { Col, Empty, Input, Pagination, Row, Space, Spin, Table } from 'antd';
 import CheckButton from '@/components/CheckButton';
 import { useCallback, useEffect, useRef, useState } from 'react';
 import type { PropertyMetadata } from '@/pages/device/Product/typings';
@@ -13,6 +13,7 @@ import PropertyLog from '../../MetadataLog/Property';
 import styles from './index.less';
 import { groupBy, throttle, toArray } from 'lodash';
 import PropertyTable from './PropertyTable';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   data: Partial<PropertyMetadata>[];
@@ -51,7 +52,7 @@ const Property = (props: Props) => {
     if (!id) return;
     const resp = await service.getProperty(params.id, id);
     if (resp.status === 200) {
-      message.success('操作成功');
+      onlyMessage('操作成功');
     }
   };
 

+ 3 - 2
src/pages/device/Instance/Detail/Tags/Edit.tsx

@@ -2,9 +2,10 @@ import { createForm } from '@formily/core';
 import { createSchemaField, FormProvider } from '@formily/react';
 import { InstanceModel, service } from '@/pages/device/Instance';
 import { ArrayTable, FormItem, Input } from '@formily/antd';
-import { message, Modal } from 'antd';
+import { Modal } from 'antd';
 import { useIntl } from 'umi';
 import GeoComponent from './location/GeoComponent';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   close: () => void;
@@ -155,7 +156,7 @@ const Edit = (props: Props) => {
         const resp = await service.saveTags(InstanceModel.detail?.id || '', list);
         if (resp.status === 200) {
           InstanceModel.detail = { ...InstanceModel.detail, tags: values.tags };
-          message.success('操作成功!');
+          onlyMessage('操作成功!');
           props.close();
         }
       }}

+ 4 - 3
src/pages/device/Instance/Detail/index.tsx

@@ -1,7 +1,7 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import { InstanceModel } from '@/pages/device/Instance';
 import { history, useParams } from 'umi';
-import { Badge, Card, Descriptions, Divider, message, Space, Tooltip } from 'antd';
+import { Badge, Card, Descriptions, Divider, Space, Tooltip } from 'antd';
 import type { ReactNode } from 'react';
 import { useEffect, useState } from 'react';
 import { observer } from '@formily/react';
@@ -27,6 +27,7 @@ import { PermissionButton } from '@/components';
 import { QuestionCircleOutlined } from '@ant-design/icons';
 import Service from '@/pages/device/Instance/service';
 import useLocation from '@/hooks/route/useLocation';
+import { onlyMessage } from '@/utils/util';
 
 export const deviceStatus = new Map();
 deviceStatus.set('online', <Badge status="success" text={'在线'} />);
@@ -302,7 +303,7 @@ const InstanceDetail = observer(() => {
                   onConfirm: async () => {
                     const resp = await service.deployDevice(params.id);
                     if (resp.status === 200) {
-                      message.success(
+                      onlyMessage(
                         intl.formatMessage({
                           id: 'pages.data.option.success',
                           defaultMessage: '操作成功!',
@@ -329,7 +330,7 @@ const InstanceDetail = observer(() => {
                   onConfirm: async () => {
                     const resp = await service.disconnectDevice(params.id);
                     if (resp.status === 200) {
-                      message.success(
+                      onlyMessage(
                         intl.formatMessage({
                           id: 'pages.data.option.success',
                           defaultMessage: '操作成功!',

+ 4 - 4
src/pages/device/Instance/Import/index.tsx

@@ -1,7 +1,7 @@
 import { FormItem, FormLayout, Select } from '@formily/antd';
 import { createForm, onFieldValueChange } from '@formily/core';
 import { createSchemaField, FormProvider } from '@formily/react';
-import { Badge, Button, Checkbox, message, Modal, Radio, Space, Upload } from 'antd';
+import { Badge, Button, Checkbox, Modal, Radio, Space, Upload } from 'antd';
 import 'antd/lib/tree-select/style/index.less';
 import { useEffect, useState } from 'react';
 import { service } from '@/pages/device/Instance';
@@ -11,7 +11,7 @@ import { UploadOutlined } from '@ant-design/icons';
 import SystemConst from '@/utils/const';
 import Token from '@/utils/token';
 import { EventSourcePolyfill } from 'event-source-polyfill';
-import { downloadFile } from '@/utils/util';
+import { downloadFile, onlyMessage } from '@/utils/util';
 import encodeQuery from '@/utils/encodeQuery';
 
 interface Props {
@@ -98,7 +98,7 @@ const NormalUpload = (props: any) => {
       };
       source.onopen = () => {};
     } else {
-      message.error('请先上传文件');
+      onlyMessage('请先上传文件', 'error');
     }
   };
   return (
@@ -112,7 +112,7 @@ const NormalUpload = (props: any) => {
           }}
           onChange={async (info) => {
             if (info.file.status === 'done') {
-              message.success('上传成功');
+              onlyMessage('上传成功');
               const resp: any = info.file.response || { result: '' };
               await submitData(resp?.result || '');
             }

+ 3 - 2
src/pages/device/Instance/Save/index.tsx

@@ -1,4 +1,4 @@
-import { Col, Form, Input, message, Modal, Row, Select } from 'antd';
+import { Col, Form, Input, Modal, Row, Select } from 'antd';
 import { service } from '@/pages/device/Instance';
 import type { DeviceInstance } from '../typings';
 import { useEffect, useState } from 'react';
@@ -6,6 +6,7 @@ import { useIntl } from '@@/plugin-locale/localeExports';
 import { UploadImage } from '@/components';
 import { debounce } from 'lodash';
 import encodeQuery from '@/utils/encodeQuery';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   visible: boolean;
@@ -85,7 +86,7 @@ const Save = (props: Props) => {
       const resp = (await service.update(values)) as any;
       setLoading(false);
       if (resp.status === 200) {
-        message.success('保存成功');
+        onlyMessage('保存成功');
         if (props.reload) {
           props.reload();
         }

+ 14 - 10
src/pages/device/Instance/index.tsx

@@ -2,7 +2,7 @@ import { PageContainer } from '@ant-design/pro-layout';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import type { DeviceInstance } from '@/pages/device/Instance/typings';
 import moment from 'moment';
-import { Badge, Button, Dropdown, Menu, message, Tooltip } from 'antd';
+import { Badge, Button, Dropdown, Menu, Tooltip } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 import { useHistory, useIntl } from 'umi';
 import {
@@ -33,6 +33,7 @@ import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { useLocation } from '@/hooks';
 import { service as deptService } from '@/pages/system/Department';
 import { service as categoryService } from '@/pages/device/Category';
+import { onlyMessage } from '@/utils/util';
 
 export const statusMap = new Map();
 statusMap.set('在线', 'success');
@@ -135,7 +136,7 @@ const Instance = () => {
           if (record.state.value !== 'notActive') {
             service.undeployDevice(record.id).then((resp: any) => {
               if (resp.status === 200) {
-                message.success(
+                onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
                     defaultMessage: '操作成功!',
@@ -147,7 +148,7 @@ const Instance = () => {
           } else {
             service.deployDevice(record.id).then((resp: any) => {
               if (resp.status === 200) {
-                message.success(
+                onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
                     defaultMessage: '操作成功!',
@@ -188,7 +189,7 @@ const Instance = () => {
         onConfirm: async () => {
           if (record.state.value === 'notActive') {
             await service.remove(record.id);
-            message.success(
+            onlyMessage(
               intl.formatMessage({
                 id: 'pages.data.option.success',
                 defaultMessage: '操作成功!',
@@ -196,7 +197,7 @@ const Instance = () => {
             );
             actionRef.current?.reload();
           } else {
-            message.error(intl.formatMessage({ id: 'pages.device.instance.deleteTip' }));
+            onlyMessage(intl.formatMessage({ id: 'pages.device.instance.deleteTip' }), 'error');
           }
         },
       }}
@@ -476,7 +477,7 @@ const Instance = () => {
               onConfirm: () => {
                 service.batchDeleteDevice(bindKeys).then((resp) => {
                   if (resp.status === 200) {
-                    message.success('操作成功');
+                    onlyMessage('操作成功');
                     actionRef.current?.reset?.();
                   }
                 });
@@ -499,7 +500,7 @@ const Instance = () => {
               onConfirm() {
                 service.batchUndeployDevice(bindKeys).then((resp) => {
                   if (resp.status === 200) {
-                    message.success('操作成功');
+                    onlyMessage('操作成功');
                     actionRef.current?.reset?.();
                   }
                 });
@@ -625,7 +626,7 @@ const Instance = () => {
                     } else {
                       await service.deployDevice(record.id);
                     }
-                    message.success(
+                    onlyMessage(
                       intl.formatMessage({
                         id: 'pages.data.option.success',
                         defaultMessage: '操作成功!',
@@ -662,7 +663,7 @@ const Instance = () => {
                   onConfirm: async () => {
                     if (record.state.value === 'notActive') {
                       await service.remove(record.id);
-                      message.success(
+                      onlyMessage(
                         intl.formatMessage({
                           id: 'pages.data.option.success',
                           defaultMessage: '操作成功!',
@@ -670,7 +671,10 @@ const Instance = () => {
                       );
                       actionRef.current?.reload();
                     } else {
-                      message.error(intl.formatMessage({ id: 'pages.device.instance.deleteTip' }));
+                      onlyMessage(
+                        intl.formatMessage({ id: 'pages.device.instance.deleteTip' }),
+                        'error',
+                      );
                     }
                   },
                 }}

+ 4 - 3
src/pages/device/Product/Detail/Access/AccessConfig/index.tsx

@@ -1,5 +1,5 @@
 import { useEffect, useState } from 'react';
-import { Col, message, Modal, Pagination, Row } from 'antd';
+import { Col, Modal, Pagination, Row } from 'antd';
 import { service } from '@/pages/link/AccessConfig';
 import { productModel } from '@/pages/device/Product';
 import SearchComponent from '@/components/SearchComponent';
@@ -10,6 +10,7 @@ import Service from '@/pages/device/Product/service';
 import AccessConfigCard from '@/components/ProTableCard/CardItems/AccessConfig';
 import { getMenuPathByCode } from '@/utils/menu';
 import PermissionButton from '@/components/PermissionButton';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   close: () => void;
@@ -101,7 +102,7 @@ const AccessConfig = (props: Props) => {
             service1.detail(productModel.current?.id || '').then((res) => {
               if (res.status === 200) {
                 productModel.current = { ...res.result };
-                message.success('操作成功!');
+                onlyMessage('操作成功!');
               }
               close();
             });
@@ -120,7 +121,7 @@ const AccessConfig = (props: Props) => {
             //   });
           }
         } else {
-          message.success('请选择接入方式');
+          onlyMessage('请选择接入方式', 'error');
         }
       }}
     >

+ 3 - 2
src/pages/device/Product/Detail/Access/index.tsx

@@ -1,4 +1,4 @@
-import { Badge, Button, Col, Empty, message, Row, Table, Tooltip } from 'antd';
+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';
@@ -14,6 +14,7 @@ import { createForm } from '@formily/core';
 import { QuestionCircleOutlined } from '@ant-design/icons';
 import TitleComponent from '@/components/TitleComponent';
 import usePermissions from '@/hooks/permission';
+import { onlyMessage } from '@/utils/util';
 
 const componentMap = {
   string: 'Input',
@@ -312,7 +313,7 @@ const Access = () => {
                     configuration: { ...values },
                   });
                   if (resp.status === 200) {
-                    message.success('操作成功!');
+                    onlyMessage('操作成功!');
                     if ((window as any).onTabSaveSuccess) {
                       if (resp.result) {
                         (window as any).onTabSaveSuccess(resp);

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

@@ -1,4 +1,4 @@
-import { Button, message, Modal, Space, Upload } from 'antd';
+import { Button, Modal, Space, Upload } from 'antd';
 import MetadataModel from '@/pages/device/components/Metadata/Base/model';
 import { FormItem, FormLayout, Radio } from '@formily/antd';
 import { createForm, onFieldValueChange } from '@formily/core';
@@ -9,7 +9,7 @@ import SystemConst from '@/utils/const';
 import Token from '@/utils/token';
 import { useParams } from 'umi';
 import { productModel, service } from '../..';
-import { downloadFile } from '@/utils/util';
+import { downloadFile, onlyMessage } from '@/utils/util';
 import type { DeviceMetadata, ProductItem } from '@/pages/device/Product/typings';
 import { Store } from 'jetlinks-store';
 import { asyncUpdateMedata, updateMetadata } from '@/pages/device/components/Metadata/metadata';
@@ -35,7 +35,7 @@ const NormalUpload = (props: any) => {
     // const resp = await service.update(_product);
     const resp = await asyncUpdateMedata(props.type, _data);
     if (resp.status === 200) {
-      message.success('操作成功');
+      onlyMessage('操作成功');
       // 刷新物模型
 
       if (props.type === 'product') {
@@ -61,7 +61,7 @@ const NormalUpload = (props: any) => {
           }}
           onChange={async (info) => {
             if (info.file.status === 'done') {
-              message.success('上传成功');
+              onlyMessage('上传成功');
               const resp: any = info.file.response || { result: '' };
               await mergeMetadata(resp?.result);
               // service.importProductProperty(param.id, resp?.result).then((r) => {

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

@@ -17,6 +17,7 @@ import MetadataMap from '@/pages/device/Instance/Detail/MetadataMap';
 import SystemConst from '@/utils/const';
 import { PermissionButton } from '@/components';
 import { QuestionCircleOutlined } from '@ant-design/icons';
+import { onlyMessage } from '@/utils/util';
 
 export const ModelEnum = {
   base: 'base',
@@ -128,7 +129,7 @@ const ProductDetail = observer(() => {
           });
         },
         error: async () => {
-          message.success('操作失败');
+          onlyMessage('操作失败', 'error');
         },
         complete: () => {
           setLoading(false);

+ 3 - 2
src/pages/device/Product/Save/index.tsx

@@ -3,9 +3,10 @@ import { service } from '@/pages/device/Product';
 import type { ProductItem } from '@/pages/device/Product/typings';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { RadioCard, UploadImage } from '@/components';
-import { Col, Form, Input, message, Modal, Row, TreeSelect } from 'antd';
+import { Col, Form, Input, Modal, Row, TreeSelect } from 'antd';
 import { useRequest } from 'umi';
 import { debounce } from 'lodash';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   visible: boolean;
@@ -81,7 +82,7 @@ const Save = (props: Props) => {
       const res = await service.update(extraFormData);
       setLoading(false);
       if (res.status === 200) {
-        message.success('保存成功');
+        onlyMessage('保存成功');
         if (props.reload) {
           props.reload();
         }

+ 9 - 9
src/pages/device/Product/index.tsx

@@ -1,5 +1,5 @@
 import { PageContainer } from '@ant-design/pro-layout';
-import { Badge, Button, message, Space, Tooltip, Upload } from 'antd';
+import { Badge, Button, Space, Tooltip, Upload } from 'antd';
 import type { ProductItem } from '@/pages/device/Product/typings';
 import {
   DeleteOutlined,
@@ -22,7 +22,7 @@ import SearchComponent from '@/components/SearchComponent';
 import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { PermissionButton, ProTableCard } from '@/components';
 import ProductCard from '@/components/ProTableCard/CardItems/product';
-import { downloadObject } from '@/utils/util';
+import { downloadObject, onlyMessage } from '@/utils/util';
 import { service as categoryService } from '@/pages/device/Category';
 import { service as deptService } from '@/pages/system/Department';
 import { omit } from 'lodash';
@@ -93,7 +93,7 @@ const Product = observer(() => {
   const deleteItem = async (id: string) => {
     const response: any = await service.remove(id);
     if (response.status === 200) {
-      message.success(
+      onlyMessage(
         intl.formatMessage({
           id: 'pages.data.option.success',
           defaultMessage: '操作成功!',
@@ -184,7 +184,7 @@ const Product = observer(() => {
             defaultMessage: '产品',
           }),
         );
-        message.success('操作成功');
+        onlyMessage('操作成功');
       }}
     >
       <DownloadOutlined />
@@ -457,7 +457,7 @@ const Product = observer(() => {
               reader.onload = async (result) => {
                 const text = result.target?.result as string;
                 if (!file.type.includes('json')) {
-                  message.error('请上传json格式文件');
+                  onlyMessage('请上传json格式文件', 'error');
                   return false;
                 }
                 try {
@@ -465,17 +465,17 @@ const Product = observer(() => {
                   // 设置导入的产品状态为未发布
                   data.state = 0;
                   if (Array.isArray(data)) {
-                    message.error('请上传json格式文件');
+                    onlyMessage('请上传json格式文件', 'error');
                     return false;
                   }
                   const res = await service.update(data);
                   if (res.status === 200) {
-                    message.success('操作成功');
+                    onlyMessage('操作成功');
                     actionRef.current?.reload();
                   }
                   return true;
                 } catch {
-                  message.error('请上传json格式文件');
+                  onlyMessage('请上传json格式文件', 'error');
                 }
                 return true;
               };
@@ -541,7 +541,7 @@ const Product = observer(() => {
                       defaultMessage: '产品',
                     }),
                   );
-                  message.success('操作成功');
+                  onlyMessage('操作成功');
                 }}
               >
                 <DownloadOutlined />

+ 3 - 2
src/pages/device/components/Alarm/Edit/index.tsx

@@ -1,4 +1,4 @@
-import { Button, Drawer, message } from 'antd';
+import { Button, Drawer } from 'antd';
 import type { Field } from '@formily/core';
 import { createForm } from '@formily/core';
 import {
@@ -29,6 +29,7 @@ import Trigger from '@/components/AlarmEditor/Trigger';
 import Action from '@/components/AlarmEditor/Action';
 import { service } from '@/pages/device/components/Alarm';
 import { useParams } from 'umi';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   visible: boolean;
@@ -304,7 +305,7 @@ const EditAlarm = (props: Props) => {
         },
       };
       await service.saveAlarm(type, id, data);
-      message.success('保存成功');
+      onlyMessage('保存成功');
       props.close();
     }
   };

+ 3 - 2
src/pages/device/components/Alarm/Record/index.tsx

@@ -4,9 +4,10 @@ import ProTable from '@jetlinks/pro-table';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { service } from '@/pages/device/components/Alarm';
 import { useParams } from 'umi';
-import { Input, message, Modal, Tag, Tooltip } from 'antd';
+import { Input, Modal, Tag, Tooltip } from 'antd';
 import { AuditOutlined, EyeOutlined } from '@ant-design/icons';
 import { useRef, useState } from 'react';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   type: 'device' | 'product';
@@ -126,7 +127,7 @@ const Record = (props: Props) => {
         onCancel={() => setVisible(false)}
         onOk={async () => {
           if (handleText === '') {
-            message.success('请填写处理结果');
+            onlyMessage('请填写处理结果', 'error');
           } else {
             const resp = await service.solve(id, handleText);
             if (resp.status === 200) {

+ 4 - 3
src/pages/device/components/Alarm/Setting/index.tsx

@@ -1,7 +1,7 @@
 import type { ProColumns } from '@jetlinks/pro-table';
 import ProTable, { ActionType } from '@jetlinks/pro-table';
 import type { AlarmSetting } from '@/pages/device/Product/typings';
-import { Button, message, Popconfirm, Space, Tooltip } from 'antd';
+import { Button, Popconfirm, Space, Tooltip } from 'antd';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { useParams } from 'umi';
 import {
@@ -15,6 +15,7 @@ import {
 import Edit from '../Edit';
 import { useRef, useState } from 'react';
 import { service } from '@/pages/device/components/Alarm';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   type: 'product' | 'device';
@@ -31,7 +32,7 @@ const Setting = (props: Props) => {
   const action = async (id: string, ac: 'start' | 'stop') => {
     const resp = await service.action(id, ac);
     if (resp.status === 200) {
-      message.success('操作成功');
+      onlyMessage('操作成功');
     }
     actionRef.current?.reload();
   };
@@ -123,7 +124,7 @@ const Setting = (props: Props) => {
           onConfirm={async () => {
             const resp = await service.remove(record.id);
             if (resp.status === 200) {
-              message.success('操作成功');
+              onlyMessage('操作成功');
             }
             actionRef.current?.reload();
           }}

+ 2 - 1
src/pages/device/components/Metadata/Base/Edit/index.tsx

@@ -52,6 +52,7 @@ import { InstanceModel } from '@/pages/device/Instance';
 import FRuleEditor from '@/components/FRuleEditor';
 import { action } from '@formily/reactive';
 import { asyncUpdateMedata, updateMetadata } from '../../metadata';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   type: 'product' | 'device';
@@ -1058,7 +1059,7 @@ const Edit = observer((props: Props) => {
         MetadataModel.item = {};
       }
     } else {
-      message.error('操作失败!');
+      onlyMessage('操作失败!', 'error');
     }
     setLoading(false);
   };

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

@@ -5,7 +5,6 @@ import { useParams } from 'umi';
 import DB from '@/db';
 import type { MetadataItem, MetadataType } from '@/pages/device/Product/typings';
 import MetadataMapping from './columns';
-import { message } from 'antd';
 import { DeleteOutlined, EditOutlined, ImportOutlined, PlusOutlined } from '@ant-design/icons';
 import Edit from './Edit';
 import { observer } from '@formily/react';
@@ -19,6 +18,7 @@ import { InstanceModel } from '@/pages/device/Instance';
 import { asyncUpdateMedata, removeMetadata } from '../metadata';
 import type { permissionType } from '@/hooks/permission';
 import { PermissionButton } from '@/components';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   type: MetadataType;
@@ -45,12 +45,12 @@ const BaseMetadata = observer((props: Props) => {
     const _currentData = removeMetadata(type, [record], typeMap.get(target), removeDB);
     const result = await asyncUpdateMedata(target, _currentData);
     if (result.status === 200) {
-      message.success('操作成功!');
+      onlyMessage('操作成功!');
       Store.set(SystemConst.REFRESH_METADATA_TABLE, true);
       MetadataModel.edit = false;
       MetadataModel.item = {};
     } else {
-      message.error('操作失败!');
+      onlyMessage('操作失败!', 'error');
     }
   };
 

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

@@ -1,4 +1,4 @@
-import { message, Modal } from 'antd';
+import { Modal } from 'antd';
 import { createSchemaField } from '@formily/react';
 import type { Field } from '@formily/core';
 import { createForm } from '@formily/core';
@@ -10,6 +10,7 @@ import { service } from '@/pages/device/Product';
 import { useParams } from 'umi';
 import { Store } from 'jetlinks-store';
 import SystemConst from '@/utils/const';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   visible: boolean;
@@ -183,17 +184,17 @@ const Import = (props: Props) => {
     if (data.metadata === 'alink') {
       service.convertMetadata('from', 'alink', data.import).subscribe({
         next: async (meta) => {
-          message.success('导入成功');
+          onlyMessage('导入成功');
           await service.modify(param.id, { metadata: JSON.stringify(meta) });
         },
         error: () => {
-          message.error('发生错误!');
+          onlyMessage('发生错误!', 'error');
         },
       });
     } else {
       const resp = await service.modify(param.id, { metadata: data[data.type] });
       if (resp.status === '200') {
-        message.success('导入成功');
+        onlyMessage('导入成功');
       }
     }
     Store.set(SystemConst.GET_METADATA, true);

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

@@ -1,5 +1,5 @@
 import { observer } from '@formily/react';
-import { message, Space, Tabs } from 'antd';
+import { Space, Tabs } from 'antd';
 import BaseMetadata from './Base';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import Import from './Import';
@@ -15,6 +15,7 @@ import { Store } from 'jetlinks-store';
 import SystemConst from '@/utils/const';
 import { useParams } from 'umi';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   tabAction?: ReactNode;
@@ -38,7 +39,7 @@ const Metadata = observer((props: Props) => {
   const resetMetadata = async () => {
     const resp = await instanceService.deleteMetadata(params.id);
     if (resp.status === 200) {
-      message.success('操作成功');
+      onlyMessage('操作成功');
       Store.set(SystemConst.REFRESH_DEVICE, true);
       setTimeout(() => {
         Store.set(SystemConst.REFRESH_METADATA_TABLE, true);

+ 1 - 1
src/pages/home/comprehensive/index.tsx

@@ -354,7 +354,7 @@ const Comprehensive = () => {
               content: '根据不同的传输类型,关联消息协议,配置设备接入网关相关参数。',
               url: require('/public/images/home/bottom-4.png'),
               onClick: () => {
-                const url = getMenuPathByCode(MENUS_CODE['link/Gateway']);
+                const url = getMenuPathByCode(MENUS_CODE['link/AccessConfig']);
                 if (!!url) {
                   history.push(url);
                 } else {

+ 1 - 1
src/pages/home/ops/index.tsx

@@ -179,7 +179,7 @@ const Ops = () => {
               content: '根据不同的传输类型,关联消息协议,配置设备接入网关相关参数。',
               url: require('/public/images/home/bottom-4.png'),
               onClick: () => {
-                const url = getMenuPathByCode(MENUS_CODE['link/Gateway']);
+                const url = getMenuPathByCode(MENUS_CODE['link/AccessConfig']);
                 if (!!url) {
                   history.push(url);
                 } else {

+ 37 - 0
src/pages/link/AccessConfig/Detail/Access/data.ts

@@ -0,0 +1,37 @@
+const MetworkTypeMapping = new Map();
+MetworkTypeMapping.set('websocket-server', 'WEB_SOCKET_SERVER');
+MetworkTypeMapping.set('http-server-gateway', 'HTTP_SERVER');
+MetworkTypeMapping.set('udp-device-gateway', 'UDP');
+MetworkTypeMapping.set('coap-server-gateway', 'COAP_SERVER');
+MetworkTypeMapping.set('mqtt-client-gateway', 'MQTT_CLIENT');
+MetworkTypeMapping.set('mqtt-server-gateway', 'MQTT_SERVER');
+MetworkTypeMapping.set('tcp-server-gateway', 'TCP_SERVER');
+
+const ProcotoleMapping = new Map();
+ProcotoleMapping.set('websocket-server', 'WebSocket');
+ProcotoleMapping.set('http-server-gateway', 'HTTP');
+ProcotoleMapping.set('udp-device-gateway', 'UDP');
+ProcotoleMapping.set('coap-server-gateway', 'COAP');
+ProcotoleMapping.set('mqtt-client-gateway', 'MQTT');
+ProcotoleMapping.set('mqtt-server-gateway', 'MQTT');
+ProcotoleMapping.set('tcp-server-gateway', 'TCP');
+ProcotoleMapping.set('child-device', '');
+
+const descriptionList = {
+  'udp-device-gateway':
+    'UDP可以让设备无需建立连接就可以与平台传输数据。在允许一定程度丢包的情况下,提供轻量化且简单的连接。',
+  'tcp-server-gateway':
+    'TCP服务是一种面向连接的、可靠的、基于字节流的传输层通信协议。设备可通过TCP服务与平台进行长链接,实时更新状态并发送消息。可自定义多种粘拆包规则,处理传输过程中可能发生的粘拆包问题。',
+  'websocket-server':
+    'WebSocket是一种在单个TCP连接上进行全双工通信的协议,允许服务端主动向客户端推送数据。设备通过WebSocket服务与平台进行长链接,实时更新状态并发送消息,且可以发布订阅消息',
+  'mqtt-client-gateway':
+    'MQTT是ISO 标准下基于发布/订阅范式的消息协议,具有轻量、简单、开放和易于实现的特点。平台使用指定的ID接入其他远程平台,订阅消息。也可添加用户名和密码校验。可设置最大消息长度。可统一设置共享的订阅前缀。',
+  'http-server-gateway':
+    'HTTP服务是一个简单的请求-响应的基于TCP的无状态协议。设备通过HTTP服务与平台进行灵活的短链接通信,仅支持设备和平台之间单对单的请求-响应模式',
+  'mqtt-server-gateway':
+    'MQTT是ISO 标准下基于发布/订阅范式的消息协议,具有轻量、简单、开放和易于实现的特点。提供MQTT的服务端,以供设备以长链接的方式接入平台。设备使用唯一的ID,也可添加用户名和密码校验。可设置最大消息长度。',
+  'coap-server-gateway':
+    'CoAP是针对只有少量的内存空间和有限的计算能力提供的一种基于UDP的协议。便于低功耗或网络受限的设备与平台通信,仅支持设备和平台之间单对单的请求-响应模式。',
+};
+
+export { MetworkTypeMapping, ProcotoleMapping, descriptionList };

+ 36 - 51
src/pages/link/AccessConfig/Detail/Access/index.tsx

@@ -1,17 +1,4 @@
-import {
-  Badge,
-  Button,
-  Card,
-  Col,
-  Empty,
-  Form,
-  Input,
-  message,
-  Row,
-  Steps,
-  Table,
-  Tooltip,
-} from 'antd';
+import { Badge, Button, Card, Col, Empty, Form, Input, Row, Steps, Table, Tooltip } from 'antd';
 import { useEffect, useState } from 'react';
 import styles from './index.less';
 import { service } from '@/pages/link/AccessConfig';
@@ -19,10 +6,12 @@ import encodeQuery from '@/utils/encodeQuery';
 import { useHistory } from 'umi';
 import ReactMarkdown from 'react-markdown';
 import { getButtonPermission, getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
-import { ExclamationCircleFilled } from '@ant-design/icons';
+import { InfoCircleOutlined } from '@ant-design/icons';
 import TitleComponent from '@/components/TitleComponent';
 import { PermissionButton } from '@/components';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
+import { MetworkTypeMapping, ProcotoleMapping, descriptionList } from './data';
 
 interface Props {
   change: () => void;
@@ -45,25 +34,6 @@ const Access = (props: Props) => {
   const protocolPermission = PermissionButton.usePermission('link/Protocol').permission;
   const [steps, setSteps] = useState<string[]>(['网络组件', '消息协议', '完成']);
 
-  const MetworkTypeMapping = new Map();
-  MetworkTypeMapping.set('websocket-server', 'WEB_SOCKET_SERVER');
-  MetworkTypeMapping.set('http-server-gateway', 'HTTP_SERVER');
-  MetworkTypeMapping.set('udp-device-gateway', 'UDP');
-  MetworkTypeMapping.set('coap-server-gateway', 'COAP_SERVER');
-  MetworkTypeMapping.set('mqtt-client-gateway', 'MQTT_CLIENT');
-  MetworkTypeMapping.set('mqtt-server-gateway', 'MQTT_SERVER');
-  MetworkTypeMapping.set('tcp-server-gateway', 'TCP_SERVER');
-
-  const ProcotoleMapping = new Map();
-  ProcotoleMapping.set('websocket-server', 'WebSocket');
-  ProcotoleMapping.set('http-server-gateway', 'HTTP');
-  ProcotoleMapping.set('udp-device-gateway', 'UDP');
-  ProcotoleMapping.set('coap-server-gateway', 'COAP');
-  ProcotoleMapping.set('mqtt-client-gateway', 'MQTT');
-  ProcotoleMapping.set('mqtt-server-gateway', 'MQTT');
-  ProcotoleMapping.set('tcp-server-gateway', 'TCP');
-  ProcotoleMapping.set('child-device', '');
-
   const queryNetworkList = (id: string, params?: any) => {
     service.getNetworkList(MetworkTypeMapping.get(id), params).then((resp) => {
       if (resp.status === 200) {
@@ -121,7 +91,7 @@ const Access = (props: Props) => {
   const next = () => {
     if (current === 0) {
       if (!networkCurrent) {
-        message.error('请选择网络组件!');
+        onlyMessage('请选择网络组件!', 'error');
       } else {
         queryProcotolList(props.provider?.id);
         setCurrent(current + 1);
@@ -129,7 +99,7 @@ const Access = (props: Props) => {
     }
     if (current === 1) {
       if (!procotolCurrent) {
-        message.error('请选择消息协议!');
+        onlyMessage('请选择消息协议!', 'error');
       } else {
         service
           .getConfigView(procotolCurrent, ProcotoleMapping.get(props.provider?.id))
@@ -276,7 +246,7 @@ const Access = (props: Props) => {
         return (
           <div>
             <div className={styles.alert}>
-              <ExclamationCircleFilled style={{ marginRight: 10 }} />
+              <InfoCircleOutlined style={{ marginRight: 10 }} />
               选择与设备通信的网络组件
             </div>
             <div className={styles.search}>
@@ -331,7 +301,11 @@ const Access = (props: Props) => {
                         setNetworkCurrent(item.id);
                       }}
                     >
-                      <div className={styles.title}>{item.name || '--'}</div>
+                      <div className={styles.title}>
+                        <Tooltip placement="topLeft" title={item.name}>
+                          {item.name}
+                        </Tooltip>
+                      </div>
                       <div className={styles.cardContent}>
                         <div
                           style={{
@@ -349,7 +323,14 @@ const Access = (props: Props) => {
                             </div>
                           ))}
                         </div>
-                        <div className={styles.desc}>{item?.description || '--'}</div>
+                        <div className={styles.desc}>
+                          <Tooltip
+                            placement="topLeft"
+                            title={item?.description || descriptionList[props.provider?.id]}
+                          >
+                            {item?.description || descriptionList[props.provider?.id]}
+                          </Tooltip>
+                        </div>
                       </div>
                     </Card>
                   </Col>
@@ -391,7 +372,7 @@ const Access = (props: Props) => {
         return (
           <div>
             <div className={styles.alert}>
-              <ExclamationCircleFilled style={{ marginRight: 10 }} />
+              <InfoCircleOutlined style={{ marginRight: 10 }} />
               使用选择的消息协议,对网络组件通信数据进行编解码、认证等操作
             </div>
             <div className={styles.search}>
@@ -444,8 +425,14 @@ const Access = (props: Props) => {
                       }}
                     >
                       <div style={{ height: '45px' }}>
-                        <div className={styles.title}>{item.name || '--'}</div>
-                        <div className={styles.desc}>{item.description || '--'}</div>
+                        <div className={styles.title}>
+                          <Tooltip title={item.name}>{item.name}</Tooltip>
+                        </div>
+                        <div className={styles.desc}>
+                          <Tooltip placement="topLeft" title={item.description}>
+                            {item.description}
+                          </Tooltip>
+                        </div>
                       </div>
                     </Card>
                   </Col>
@@ -467,7 +454,6 @@ const Access = (props: Props) => {
                           const tab: any = window.open(`${origin}/#${url}?save=true`);
                           tab!.onTabSaveSuccess = (resp: any) => {
                             if (resp.status === 200) {
-                              console.log(props.provider);
                               queryProcotolList(props.provider?.id);
                             }
                           };
@@ -531,7 +517,7 @@ const Access = (props: Props) => {
                             })
                             .then((resp: any) => {
                               if (resp.status === 200) {
-                                message.success('操作成功!');
+                                onlyMessage('操作成功!');
                                 history.goBack();
                                 if ((window as any).onTabSaveSuccess) {
                                   (window as any).onTabSaveSuccess(resp);
@@ -551,7 +537,7 @@ const Access = (props: Props) => {
                             })
                             .then((resp: any) => {
                               if (resp.status === 200) {
-                                message.success('操作成功!');
+                                onlyMessage('操作成功!');
                                 history.goBack();
                                 if ((window as any).onTabSaveSuccess) {
                                   (window as any).onTabSaveSuccess(resp);
@@ -574,17 +560,17 @@ const Access = (props: Props) => {
               <div className={styles.config}>
                 <div className={styles.item}>
                   <div className={styles.title}>接入方式</div>
-                  <div className={styles.context}>{props.provider?.name || '--'}</div>
-                  <div className={styles.context}>{props.provider?.description || '--'}</div>
+                  <div className={styles.context}>{props.provider?.name}</div>
+                  <div className={styles.context}>{props.provider?.description}</div>
                 </div>
                 <div className={styles.item}>
                   <div className={styles.title}>消息协议</div>
                   <div className={styles.context}>
-                    {procotolList.find((i) => i.id === procotolCurrent)?.name || '--'}
+                    {procotolList.find((i) => i.id === procotolCurrent)?.name}
                   </div>
                   {config?.document && (
                     <div className={styles.context}>
-                      {<ReactMarkdown>{config?.document}</ReactMarkdown> || '--'}
+                      {<ReactMarkdown>{config?.document}</ReactMarkdown>}
                     </div>
                   )}
                 </div>
@@ -597,12 +583,11 @@ const Access = (props: Props) => {
                             <Badge
                               color={item.health === -1 ? 'red' : 'green'}
                               text={item.address}
-                              style={{ marginLeft: '20px' }}
                             />
                           </div>
                         ),
                       )
-                    : '--'}
+                    : ''}
                 </div>
                 {config?.routes && config?.routes?.length > 0 && (
                   <div className={styles.item}>

+ 3 - 2
src/pages/link/AccessConfig/Detail/Channel/index.tsx

@@ -1,4 +1,4 @@
-import { Button, Card, Col, Form, Input, message, Row } from 'antd';
+import { Button, Card, Col, Form, Input, Row } from 'antd';
 import { useEffect, useState } from 'react';
 import { service } from '@/pages/link/AccessConfig';
 import { ProcotoleMapping } from '../Cloud/Protocol';
@@ -6,6 +6,7 @@ import TitleComponent from '@/components/TitleComponent';
 import { getButtonPermission } from '@/utils/menu';
 import ReactMarkdown from 'react-markdown';
 import { useHistory } from 'umi';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   change: () => void;
@@ -87,7 +88,7 @@ const Media = (props: Props) => {
                       };
                       const resp: any = await service[!props.data?.id ? 'save' : 'update'](param);
                       if (resp.status === 200) {
-                        message.success('操作成功!');
+                        onlyMessage('操作成功!');
                         history.goBack();
                       }
                     } catch (errorInfo) {

+ 3 - 2
src/pages/link/AccessConfig/Detail/Cloud/Finish/index.tsx

@@ -1,11 +1,12 @@
 import { TitleComponent } from '@/components';
 import { getButtonPermission } from '@/utils/menu';
-import { Button, Col, Form, Input, message, Row } from 'antd';
+import { Button, Col, Form, Input, Row } from 'antd';
 import { service } from '@/pages/link/AccessConfig';
 import { useHistory } from 'umi';
 import { useEffect, useState } from 'react';
 import ReactMarkdown from 'react-markdown';
 import { ProcotoleMapping } from '../Protocol';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   prev: () => void;
@@ -79,7 +80,7 @@ const Finish = (props: Props) => {
                   };
                   const resp: any = await service[!props.data?.id ? 'save' : 'update'](param);
                   if (resp.status === 200) {
-                    message.success('操作成功!');
+                    onlyMessage('操作成功!');
                     history.goBack();
                     if ((window as any).onTabSaveSuccess) {
                       (window as any).onTabSaveSuccess(resp);

+ 3 - 3
src/pages/link/AccessConfig/Detail/Cloud/index.tsx

@@ -1,7 +1,7 @@
 import { Button, Card, Steps } from 'antd';
 import { useEffect, useState } from 'react';
 import styles from './index.less';
-import { ExclamationCircleFilled } from '@ant-design/icons';
+import { InfoCircleOutlined } from '@ant-design/icons';
 import OneNet from './OneNet';
 import CTWing from './CTWing';
 import Protocol from './Protocol';
@@ -40,7 +40,7 @@ const Cloud = (props: Props) => {
         return (
           <div>
             <div className={styles.alert}>
-              <ExclamationCircleFilled style={{ marginRight: 10 }} />
+              <InfoCircleOutlined style={{ marginRight: 10 }} />
               通过{props?.provider?.id === 'OneNet' ? 'OneNet' : 'CTWing'}
               平台的HTTP推送服务进行数据接入
             </div>
@@ -57,7 +57,7 @@ const Cloud = (props: Props) => {
         return (
           <div>
             <div className={styles.alert}>
-              <ExclamationCircleFilled style={{ marginRight: 10 }} />
+              <InfoCircleOutlined style={{ marginRight: 10 }} />
               只能选择HTTP通信方式的协议
             </div>
             <div style={{ marginTop: 10 }}>

+ 5 - 5
src/pages/link/AccessConfig/Detail/Media/index.tsx

@@ -1,4 +1,4 @@
-import { Button, Card, Col, Form, Input, message, Row, Steps } from 'antd';
+import { Button, Card, Col, Form, Input, Row, Steps } from 'antd';
 import { useEffect, useState } from 'react';
 import styles from './index.less';
 import {
@@ -19,8 +19,8 @@ import { service } from '@/pages/link/AccessConfig';
 import { useLocation } from 'umi';
 import SipComponent from '@/components/SipComponent';
 import TitleComponent from '@/components/TitleComponent';
-import { ExclamationCircleFilled } from '@ant-design/icons';
-import { testIP } from '@/utils/util';
+import { InfoCircleOutlined } from '@ant-design/icons';
+import { onlyMessage, testIP } from '@/utils/util';
 import { getButtonPermission } from '@/utils/menu';
 
 type LocationType = {
@@ -395,7 +395,7 @@ const Media = (props: Props) => {
     return (
       <div>
         <div className={styles.alert}>
-          <ExclamationCircleFilled style={{ marginRight: 10 }} />
+          <InfoCircleOutlined style={{ marginRight: 10 }} />
           配置设备信令参数
         </div>
         <AForm form={aform} layout="vertical" style={{ padding: 30 }}>
@@ -507,7 +507,7 @@ const Media = (props: Props) => {
                     resp = await service.save({ ...param });
                   }
                   if (resp.status === 200) {
-                    message.success('操作成功!');
+                    onlyMessage('操作成功!');
                     if (params.get('save')) {
                       if ((window as any).onTabSaveSuccess) {
                         if (resp.result) {

+ 6 - 5
src/pages/link/AccessConfig/index.tsx

@@ -2,7 +2,7 @@ import SearchComponent from '@/components/SearchComponent';
 import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 import { PageContainer } from '@ant-design/pro-layout';
 import type { ProColumns } from '@jetlinks/pro-table';
-import { Card, Col, message, Pagination, Row } from 'antd';
+import { Card, Col, Pagination, Row } from 'antd';
 import { useEffect, useState } from 'react';
 import { useHistory } from 'umi';
 import Service from './service';
@@ -11,6 +11,7 @@ import AccessConfigCard from '@/components/ProTableCard/CardItems/AccessConfig';
 import { PermissionButton, Empty } from '@/components';
 import { useDomFullHeight } from '@/hooks';
 import { Store } from 'jetlinks-store';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('gateway/device');
 
@@ -146,14 +147,14 @@ const AccessConfig = () => {
                           if (item.state.value !== 'disabled') {
                             service.shutDown(item.id).then((resp) => {
                               if (resp.status === 200) {
-                                message.success('操作成功!');
+                                onlyMessage('操作成功!');
                                 handleSearch(param);
                               }
                             });
                           } else {
                             service.startUp(item.id).then((resp) => {
                               if (resp.status === 200) {
-                                message.success('操作成功!');
+                                onlyMessage('操作成功!');
                                 handleSearch(param);
                               }
                             });
@@ -180,10 +181,10 @@ const AccessConfig = () => {
                         onConfirm: () => {
                           service.remove(item.id).then((resp: any) => {
                             if (resp.status === 200) {
-                              message.success('操作成功!');
+                              onlyMessage('操作成功!');
                               handleSearch(param);
                             } else {
-                              message.error(resp?.message || '操作失败');
+                              onlyMessage(resp?.message || '操作失败', 'error');
                             }
                           });
                         },

+ 4 - 3
src/pages/link/Certificate/Detail/components/CertificateFile/index.tsx

@@ -1,7 +1,8 @@
 import SystemConst from '@/utils/const';
 import Token from '@/utils/token';
+import { onlyMessage } from '@/utils/util';
 import { UploadOutlined } from '@ant-design/icons';
-import { Button, Input, message, Upload } from 'antd';
+import { Button, Input, Upload } from 'antd';
 import type { UploadChangeParam } from 'antd/lib/upload';
 import { useEffect, useState } from 'react';
 
@@ -23,14 +24,14 @@ const CertificateFile = (props: Props) => {
         file: { response },
       } = info;
       if (response.status === 200) {
-        message.success('上传成功');
+        onlyMessage('上传成功');
         setKeystoreBase64(response.result);
         if (props.onChange) {
           props.onChange(response.result);
         }
       }
     } else if (info.file.status === 'error') {
-      message.error(`${info.file.name} file upload failed.`);
+      onlyMessage(`${info.file.name} file upload failed.`, 'error');
     }
   };
 

+ 3 - 2
src/pages/link/Certificate/Detail/index.tsx

@@ -3,7 +3,7 @@ import usePermissions from '@/hooks/permission';
 import { PageContainer } from '@ant-design/pro-layout';
 import { Form, FormButtonGroup, FormItem } from '@formily/antd';
 import type { ISchema } from '@formily/json-schema';
-import { Card, Col, Input, message, Row } from 'antd';
+import { Card, Col, Input, Row } from 'antd';
 import { createSchemaField, observer } from '@formily/react';
 import { useEffect, useMemo } from 'react';
 import { createForm } from '@formily/core';
@@ -12,6 +12,7 @@ import Standard from './components/Standard';
 import { service } from '@/pages/link/Certificate';
 import { useParams } from 'umi';
 import './index.less';
+import { onlyMessage } from '@/utils/util';
 
 const Detail = observer(() => {
   const params = useParams<{ id: string }>();
@@ -146,7 +147,7 @@ const Detail = observer(() => {
                         ? await service.update(data)
                         : await service.save(data);
                       if (response.status === 200) {
-                        message.success('操作成功');
+                        onlyMessage('操作成功');
                         history.back();
                       }
                     }}

+ 3 - 2
src/pages/link/Certificate/index.tsx

@@ -2,7 +2,7 @@ import { PageContainer } from '@ant-design/pro-layout';
 import { useRef, useState } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
-import { message, Tooltip } from 'antd';
+import { Tooltip } from 'antd';
 import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import SearchComponent from '@/components/SearchComponent';
@@ -12,6 +12,7 @@ import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { history } from 'umi';
 import Service from '../service';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('network/certificate');
 
@@ -85,7 +86,7 @@ const Certificate = () => {
             title: '确认删除?',
             onConfirm: async () => {
               await service.remove(record.id);
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',

+ 3 - 2
src/pages/link/Channel/Modbus/Access/addPoint/index.tsx

@@ -1,6 +1,7 @@
-import { Col, Form, Input, InputNumber, message, Modal, Row, Select } from 'antd';
+import { Col, Form, Input, InputNumber, Modal, Row, Select } from 'antd';
 import { useEffect, useState } from 'react';
 import { service } from '@/pages/link/Channel/Modbus';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   data: any;
@@ -25,7 +26,7 @@ const AddPoint = (props: Props) => {
       })
       .then((res: any) => {
         if (res.status === 200) {
-          message.success('操作成功!');
+          onlyMessage('操作成功!');
           props.close();
         }
       });

+ 4 - 3
src/pages/link/Channel/Modbus/Access/bindDevice/index.tsx

@@ -1,10 +1,11 @@
 import { Modal } from '@/components';
 import SearchComponent from '@/components/SearchComponent';
 import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { Badge, message } from 'antd';
+import { Badge } from 'antd';
 import { useRef, useState } from 'react';
 import { service } from '@/pages/link/Channel/Modbus';
 import moment from 'moment';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   id: string;
@@ -61,12 +62,12 @@ const BindDevice = (props: Props) => {
     if (keys && keys.length !== 0) {
       service.bind(keys, props.id).then((res) => {
         if (res.status === 200) {
-          message.success('绑定成功');
+          onlyMessage('绑定成功');
           props.close();
         }
       });
     } else {
-      message.error('请勾选数据');
+      onlyMessage('请勾选数据', 'error');
     }
   };
 

+ 5 - 4
src/pages/link/Channel/Modbus/Access/index.tsx

@@ -1,7 +1,7 @@
 import PermissionButton from '@/components/PermissionButton';
 import { PageContainer } from '@ant-design/pro-layout';
 import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { Badge, Card, Empty, Input, message, Popconfirm, Tabs, Tooltip } from 'antd';
+import { Badge, Card, Empty, Input, Popconfirm, Tabs, Tooltip } from 'antd';
 import { useIntl, useLocation } from 'umi';
 import { useEffect, useRef, useState } from 'react';
 import {
@@ -20,6 +20,7 @@ import AddPoint from './addPoint';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
 import { map } from 'rxjs/operators';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 const Access = () => {
   const intl = useIntl();
@@ -112,7 +113,7 @@ const Access = () => {
                 state: record.state?.value === 'enabled' ? 'disabled' : 'enabled',
               };
               await service.saveMetadataConfig(opcUaId, deviceId, item);
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',
@@ -150,7 +151,7 @@ const Access = () => {
             onConfirm: async () => {
               const resp: any = await service.removeMetadataConfig(record.id);
               if (resp.status === 200) {
-                message.success(
+                onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
                     defaultMessage: '操作成功!',
@@ -307,7 +308,7 @@ const Access = () => {
                           onConfirm={() => {
                             service.unbind([item.id], opcUaId).then((res: any) => {
                               if (res.status === 200) {
-                                message.success('解绑成功');
+                                onlyMessage('解绑成功');
                                 getBindList(opcUaId);
                               }
                             });

+ 4 - 4
src/pages/link/Channel/Modbus/Save/index.tsx

@@ -5,8 +5,8 @@ import { Form, FormGrid, FormItem, Input, NumberPicker, Select } from '@formily/
 import type { ISchema } from '@formily/json-schema';
 import { service } from '@/pages/link/Channel/Modbus';
 import { Modal } from '@/components';
-import { message } from 'antd';
 import { useEffect } from 'react';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   data: any;
@@ -137,7 +137,7 @@ const Save = (props: Props) => {
         })
         .then((res: any) => {
           if (res.status === 200) {
-            message.success('保存成功');
+            onlyMessage('保存成功');
             props.close();
           }
         });
@@ -147,7 +147,7 @@ const Save = (props: Props) => {
           if (res.status === 200) {
             service.bind([props.device.id], res.result.id).then((resp: any) => {
               if (resp.status === 200) {
-                message.success('保存成功');
+                onlyMessage('保存成功');
                 props.close();
               }
             });
@@ -156,7 +156,7 @@ const Save = (props: Props) => {
       } else {
         service.save(value).then((res: any) => {
           if (res.status === 200) {
-            message.success('保存成功');
+            onlyMessage('保存成功');
             props.close();
           }
         });

+ 4 - 3
src/pages/link/Channel/Modbus/index.tsx

@@ -1,6 +1,6 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { Badge, Card, Col, message, Row } from 'antd';
+import { Badge, Card, Col, Row } from 'antd';
 import styles from './index.less';
 import { PermissionButton } from '@/components';
 import { history, useIntl } from 'umi';
@@ -18,6 +18,7 @@ import Service from './service';
 import Save from './Save';
 import { getMenuPathByCode } from '@/utils/menu';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('modbus/master');
 
@@ -123,7 +124,7 @@ const Modbus = () => {
                   state: 'disabled',
                 });
               }
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',
@@ -166,7 +167,7 @@ const Modbus = () => {
             onConfirm: async () => {
               const resp: any = await service.remove(record.id);
               if (resp.status === 200) {
-                message.success(
+                onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
                     defaultMessage: '操作成功!',

+ 6 - 5
src/pages/link/Channel/Opcua/Access/addPoint/index.tsx

@@ -1,7 +1,8 @@
-import { Col, Form, Input, InputNumber, message, Modal, Radio, Row, Select } from 'antd';
+import { Col, Form, Input, InputNumber, Modal, Radio, Row, Select } from 'antd';
 import { useEffect, useState } from 'react';
 import { service } from '@/pages/link/Channel/Opcua';
 import { DataTypeList } from '@/pages/device/data';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   data: any;
@@ -37,7 +38,7 @@ const AddPoint = (props: Props) => {
           )
           .then((res) => {
             if (res.status === 200) {
-              message.success('保存成功');
+              onlyMessage('保存成功');
               props.close();
             }
           });
@@ -54,7 +55,7 @@ const AddPoint = (props: Props) => {
           )
           .then((res) => {
             if (res.status === 200) {
-              message.success('保存成功');
+              onlyMessage('保存成功');
               props.close();
             }
           });
@@ -75,7 +76,7 @@ const AddPoint = (props: Props) => {
           })
           .then((res) => {
             if (res.status === 200) {
-              message.success('保存成功');
+              onlyMessage('保存成功');
               props.close();
             }
           });
@@ -89,7 +90,7 @@ const AddPoint = (props: Props) => {
           })
           .then((res) => {
             if (res.status === 200) {
-              message.success('保存成功');
+              onlyMessage('保存成功');
               props.close();
             }
           });

+ 4 - 3
src/pages/link/Channel/Opcua/Access/bindDevice/index.tsx

@@ -1,10 +1,11 @@
 import { Modal } from '@/components';
 import SearchComponent from '@/components/SearchComponent';
 import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { Badge, message } from 'antd';
+import { Badge } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 import { service } from '@/pages/link/Channel/Opcua';
 import moment from 'moment';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   id: string;
@@ -67,12 +68,12 @@ const BindDevice = (props: Props) => {
       }));
       service.bind(params).then((res) => {
         if (res.status === 200) {
-          message.success('绑定成功');
+          onlyMessage('绑定成功');
           props.close();
         }
       });
     } else {
-      message.error('请勾选数据');
+      onlyMessage('请勾选数据', 'error');
     }
   };
 

+ 5 - 4
src/pages/link/Channel/Opcua/Access/index.tsx

@@ -1,7 +1,7 @@
 import PermissionButton from '@/components/PermissionButton';
 import { PageContainer } from '@ant-design/pro-layout';
 import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { Badge, Card, Empty, Input, message, Popconfirm, Tabs, Tooltip } from 'antd';
+import { Badge, Card, Empty, Input, Popconfirm, Tabs, Tooltip } from 'antd';
 import { useIntl, useLocation } from 'umi';
 import { useEffect, useRef, useState } from 'react';
 import {
@@ -20,6 +20,7 @@ import AddPoint from './addPoint';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
 import { map } from 'rxjs/operators';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 const Access = () => {
   const intl = useIntl();
@@ -119,7 +120,7 @@ const Access = () => {
               } else {
                 await service.stopPoint(bindDeviceId, [record.id]);
               }
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',
@@ -157,7 +158,7 @@ const Access = () => {
             onConfirm: async () => {
               const resp: any = await service.deletePoint(record.id);
               if (resp.status === 200) {
-                message.success(
+                onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
                     defaultMessage: '操作成功!',
@@ -308,7 +309,7 @@ const Access = () => {
                           onConfirm={() => {
                             service.unbind([item.deviceId], opcUaId).then((res: any) => {
                               if (res.status === 200) {
-                                message.success('解绑成功');
+                                onlyMessage('解绑成功');
                                 getBindList(
                                   encodeQuery({
                                     terms: {

+ 4 - 4
src/pages/link/Channel/Opcua/Save/index.tsx

@@ -5,11 +5,11 @@ import { Form, FormGrid, FormItem, Input, Select } from '@formily/antd';
 import type { ISchema } from '@formily/json-schema';
 import { service } from '@/pages/link/Channel/Opcua';
 import { Modal } from '@/components';
-import { message } from 'antd';
 import { useMemo } from 'react';
 import { action } from '@formily/reactive';
 import type { Response } from '@/utils/typings';
 import type { Field } from '@formily/core';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   data: Partial<OpaUa>;
@@ -237,7 +237,7 @@ const Save = (props: Props) => {
     if (props.data.id) {
       service.modify(props.data.id, item).then((res: any) => {
         if (res.status === 200) {
-          message.success('保存成功');
+          onlyMessage('保存成功');
           props.close();
         }
       });
@@ -254,7 +254,7 @@ const Save = (props: Props) => {
             };
             service.bind(params).then((resp) => {
               if (resp.status === 200) {
-                message.success('保存成功');
+                onlyMessage('保存成功');
                 props.close();
               }
             });
@@ -263,7 +263,7 @@ const Save = (props: Props) => {
       } else {
         service.save(item).then((res: any) => {
           if (res.status === 200) {
-            message.success('保存成功');
+            onlyMessage('保存成功');
             props.close();
           }
         });

+ 5 - 4
src/pages/link/Channel/Opcua/index.tsx

@@ -1,6 +1,6 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { Badge, Card, Col, message, Row } from 'antd';
+import { Badge, Card, Col, Row } from 'antd';
 import styles from './index.less';
 import { PermissionButton } from '@/components';
 import { history, useIntl } from 'umi';
@@ -18,6 +18,7 @@ import Service from './service';
 import Save from './Save';
 import { getMenuPathByCode } from '@/utils/menu';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('opc/client');
 
@@ -119,7 +120,7 @@ const Opcua = () => {
               if (record.state.value === 'disabled') {
                 const res = await service.enable(record.id);
                 if (res.status === 200) {
-                  message.success(
+                  onlyMessage(
                     intl.formatMessage({
                       id: 'pages.data.option.success',
                       defaultMessage: '操作成功!',
@@ -130,7 +131,7 @@ const Opcua = () => {
               } else {
                 const res = await service.disable(record.id);
                 if (res.status === 200) {
-                  message.success(
+                  onlyMessage(
                     intl.formatMessage({
                       id: 'pages.data.option.success',
                       defaultMessage: '操作成功!',
@@ -175,7 +176,7 @@ const Opcua = () => {
             onConfirm: async () => {
               const resp: any = await service.remove(record.id);
               if (resp.status === 200) {
-                message.success(
+                onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
                     defaultMessage: '操作成功!',

+ 5 - 5
src/pages/link/Gateway/index.tsx

@@ -2,7 +2,7 @@ import { PageContainer } from '@ant-design/pro-layout';
 import type { GatewayItem } from '@/pages/link/Gateway/typings';
 import { useRef } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { message, Popconfirm, Tooltip } from 'antd';
+import { Popconfirm, Tooltip } from 'antd';
 import {
   EditOutlined,
   MinusOutlined,
@@ -19,7 +19,7 @@ import { CurdModel } from '@/components/BaseCrud/model';
 import type { Field, FormPathPattern } from '@formily/core';
 import { onFieldReact, onFieldValueChange } from '@formily/core';
 import { action } from '@formily/reactive';
-import { useAsyncDataSource } from '@/utils/util';
+import { onlyMessage, useAsyncDataSource } from '@/utils/util';
 
 export const service = new Service('gateway/device');
 
@@ -30,9 +30,9 @@ const Gateway = () => {
   const handleAction = async (id: string, type: 'shutdown' | 'startup' | 'pause') => {
     const resp = await service.action(id, type);
     if (resp.status === 200) {
-      message.success('操作成功!');
+      onlyMessage('操作成功!');
     } else {
-      message.error('操作失败');
+      onlyMessage('操作失败', 'error');
     }
     actionRef.current?.reload();
   };
@@ -132,7 +132,7 @@ const Gateway = () => {
             <Popconfirm
               onConfirm={async () => {
                 await service.remove(record.id);
-                message.success(
+                onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
                     defaultMessage: '操作成功!',

+ 3 - 2
src/pages/link/Protocol/FileUpload/index.tsx

@@ -2,8 +2,9 @@ import SystemConst from '@/utils/const';
 import Token from '@/utils/token';
 import { useState } from 'react';
 import { connect } from '@formily/react';
-import { Button, Input, message, Spin, Upload } from 'antd';
+import { Button, Input, Spin, Upload } from 'antd';
 import type { UploadChangeParam } from 'antd/lib/upload/interface';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   value: string;
@@ -18,7 +19,7 @@ const FileUpload = connect((props: Props) => {
   const handleChange = (info: UploadChangeParam) => {
     setLoading(true);
     if (info.file.status === 'done') {
-      message.success('上传成功!');
+      onlyMessage('上传成功!');
       info.file.url = info.file.response?.result;
       setUrl(info.file.response?.result);
       setLoading(false);

+ 8 - 7
src/pages/link/Protocol/index.tsx

@@ -1,7 +1,7 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import type { ProtocolItem } from '@/pages/link/Protocol/typings';
-import { Badge, message } from 'antd';
+import { Badge } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 import {
   DeleteOutlined,
@@ -16,6 +16,7 @@ import SearchComponent from '@/components/SearchComponent';
 import { PermissionButton, ProTableCard } from '@/components';
 import ProcotolCard from '@/components/ProTableCard/CardItems/protocol';
 import Save from './save';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('protocol');
 
@@ -30,9 +31,9 @@ const Protocol = () => {
   const modifyState = async (id: string, type: 'deploy' | 'un-deploy') => {
     const resp = await service.modifyState(id, type);
     if (resp.status === 200) {
-      message.success('操作成功!');
+      onlyMessage('操作成功!');
     } else {
-      message.error(resp?.message || '操作失败');
+      onlyMessage(resp?.message || '操作失败', 'error');
     }
     actionRef.current?.reload();
   };
@@ -153,7 +154,7 @@ const Protocol = () => {
             onConfirm: async () => {
               const resp: any = await service.remove(record.id);
               if (resp.status === 200) {
-                message.success(
+                onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
                     defaultMessage: '操作成功!',
@@ -161,7 +162,7 @@ const Protocol = () => {
                 );
                 actionRef.current?.reload();
               } else {
-                message.error(resp?.message || '操作失败');
+                onlyMessage(resp?.message || '操作失败', 'error');
               }
             },
           }}
@@ -288,7 +289,7 @@ const Protocol = () => {
                   onConfirm: async () => {
                     const resp: any = await service.remove(record.id);
                     if (resp.status === 200) {
-                      message.success(
+                      onlyMessage(
                         intl.formatMessage({
                           id: 'pages.data.option.success',
                           defaultMessage: '操作成功!',
@@ -296,7 +297,7 @@ const Protocol = () => {
                       );
                       actionRef.current?.reload();
                     } else {
-                      message.error(resp?.message || '操作失败');
+                      onlyMessage(resp?.message || '操作失败', 'error');
                     }
                   },
                 }}

+ 3 - 3
src/pages/link/Type/Detail/index.tsx

@@ -17,9 +17,9 @@ import type { ISchema } from '@formily/json-schema';
 import { useEffect, useMemo, useRef } from 'react';
 import type { Field } from '@formily/core';
 import { createForm, onFieldReact, onFieldValueChange } from '@formily/core';
-import { Card, message } from 'antd';
+import { Card } from 'antd';
 import styles from './index.less';
-import { useAsyncDataSource } from '@/utils/util';
+import { onlyMessage, useAsyncDataSource } from '@/utils/util';
 import { service } from '../index';
 import _ from 'lodash';
 import FAutoComplete from '@/components/FAutoComplete';
@@ -714,7 +714,7 @@ const Save = observer(() => {
     }
     const response: any = data.id ? await service.update(data) : await service.save(data);
     if (response.status === 200) {
-      message.success('保存成功');
+      onlyMessage('保存成功');
       history.back();
       if ((window as any).onTabSaveSuccess) {
         if (response.result?.id) {

+ 6 - 5
src/pages/link/Type/index.tsx

@@ -1,6 +1,6 @@
 import { useRef, useState } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { Badge, message, Popconfirm, Tooltip } from 'antd';
+import { Badge, Popconfirm, Tooltip } from 'antd';
 import {
   CloseCircleOutlined,
   DeleteOutlined,
@@ -19,6 +19,7 @@ import { Store } from 'jetlinks-store';
 import { PermissionButton, ProTableCard } from '@/components';
 import NetworkCard from '@/components/ProTableCard/CardItems/networkCard';
 import usePermissions from '@/hooks/permission';
+import { onlyMessage } from '@/utils/util';
 
 export const service = new Service('network/config');
 
@@ -185,7 +186,7 @@ const Network = () => {
                 enabled: 'shutdown',
               };
               await service.changeState(record.id, map[record.state.value]);
-              message.success(
+              onlyMessage(
                 intl.formatMessage({
                   id: 'pages.data.option.success',
                   defaultMessage: '操作成功!',
@@ -219,7 +220,7 @@ const Network = () => {
             onConfirm={async () => {
               const response: any = await service.remove(record.id);
               if (response.status === 200) {
-                message.success('删除成功');
+                onlyMessage('删除成功');
                 actionRef.current?.reload();
               }
             }}
@@ -305,7 +306,7 @@ const Network = () => {
                       enabled: 'shutdown',
                     };
                     await service.changeState(record.id, map[record.state.value]);
-                    message.success(
+                    onlyMessage(
                       intl.formatMessage({
                         id: 'pages.data.option.success',
                         defaultMessage: '操作成功!',
@@ -342,7 +343,7 @@ const Network = () => {
                   onConfirm={async () => {
                     const response: any = await service.remove(record.id);
                     if (response.status === 200) {
-                      message.success('删除成功');
+                      onlyMessage('删除成功');
                       actionRef.current?.reload();
                     }
                   }}

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

@@ -1,11 +1,12 @@
 import SearchComponent from '@/components/SearchComponent';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
-import { message, Modal, Space } from 'antd';
+import { Modal, Space } from 'antd';
 import { useRef, useState } from 'react';
 import { service } from '@/pages/media/Cascade';
 import { useIntl } from 'umi';
 import BadgeStatus, { StatusColorEnum } from '@/components/BadgeStatus';
+import { onlyMessage } from '@/utils/util';
 
 interface Props {
   data: string;
@@ -85,11 +86,11 @@ const BindChannel = (props: Props) => {
         if (selectedRowKey.length > 0) {
           const resp = await service.bindChannel(props.data, selectedRowKey);
           if (resp.status === 200) {
-            message.success('操作成功!');
+            onlyMessage('操作成功!');
             props.close();
           }
         } else {
-          message.error('请勾选数据');
+          onlyMessage('请勾选数据', 'error');
         }
       }}
       width={1200}

+ 6 - 5
src/pages/media/Cascade/Channel/index.tsx

@@ -4,13 +4,14 @@ import { CloseOutlined, DisconnectOutlined, EditOutlined } from '@ant-design/ico
 import { PageContainer } from '@ant-design/pro-layout';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
-import { Button, Input, message, Popover, Space } from 'antd';
+import { Button, Input, Popover, Space } from 'antd';
 import { useRef, useState } from 'react';
 import { useIntl, useLocation } from 'umi';
 import BindChannel from './BindChannel';
 import BadgeStatus, { StatusColorEnum } from '@/components/BadgeStatus';
 import { PermissionButton } from '@/components';
 import { useDomFullHeight } from '@/hooks';
+import { onlyMessage } from '@/utils/util';
 
 const Channel = () => {
   const location: any = useLocation();
@@ -29,7 +30,7 @@ const Channel = () => {
     const resp = await service.unbindChannel(id, list);
     if (resp.status === 200) {
       actionRef.current?.reload();
-      message.success('操作成功!');
+      onlyMessage('操作成功!');
       if (list.length === 1) {
         const index = selectedRowKey.indexOf(list[0]);
         const dt = [...selectedRowKey];
@@ -58,12 +59,12 @@ const Channel = () => {
                 gbChannelId: data,
               });
               if (resp.status === 200) {
-                message.success('操作成功');
+                onlyMessage('操作成功');
                 actionRef.current?.reload();
                 setPopvisible('');
               }
             } else {
-              message.error('请输入国标ID');
+              onlyMessage('请输入国标ID', 'error');
             }
           }}
         >
@@ -265,7 +266,7 @@ const Channel = () => {
                   unbind(selectedRowKey);
                   setSelectedRowKey([]);
                 } else {
-                  message.error('请先选择需要解绑的通道列表');
+                  onlyMessage('请先选择需要解绑的通道列表', 'error');
                 }
               },
             }}

+ 35 - 0
src/pages/media/Cascade/Save/index.less

@@ -0,0 +1,35 @@
+.doc {
+  height: 1050px;
+  padding: 24px;
+  overflow-y: auto;
+  color: rgba(#000, 0.8);
+  font-size: 14px;
+  background-color: #fafafa;
+
+  .url {
+    padding: 8px 16px;
+    color: #2f54eb;
+    background-color: rgba(#a7bdf7, 0.2);
+  }
+
+  h1 {
+    margin: 16px 0;
+    color: rgba(#000, 0.85);
+    font-weight: bold;
+    font-size: 14px;
+
+    &:first-child {
+      margin-top: 0;
+    }
+  }
+
+  h2 {
+    margin: 6px 0;
+    color: rgba(0, 0, 0, 0.8);
+    font-size: 14px;
+  }
+
+  .image {
+    margin: 16px 0;
+  }
+}

+ 322 - 252
src/pages/media/Cascade/Save/index.tsx

@@ -1,5 +1,5 @@
 import TitleComponent from '@/components/TitleComponent';
-import { QuestionCircleOutlined } from '@ant-design/icons';
+import { InfoCircleFilled, QuestionCircleOutlined } from '@ant-design/icons';
 import { PageContainer } from '@ant-design/pro-layout';
 import {
   Button,
@@ -13,6 +13,8 @@ import {
   Row,
   Select,
   Tooltip,
+  Image,
+  Alert,
 } from 'antd';
 import SipComponent from '@/components/SipComponent';
 import SipSelectComponent from '@/components/SipSelectComponent';
@@ -20,6 +22,7 @@ import { testIP } from '@/utils/util';
 import { useEffect, useState } from 'react';
 import { service } from '../index';
 import { useLocation } from 'umi';
+import styles from './index.less';
 
 const Save = () => {
   const location: any = useLocation();
@@ -99,262 +102,329 @@ const Save = () => {
     return Promise.reject(new Error('请输入1~10000之间的数字'));
   };
 
+  const img1 = require('/public/images/northbound/doc1.png');
+  const img2 = require('/public/images/northbound/doc2.png');
+  const img3 = require('/public/images/northbound/doc3.png');
+
   return (
     <PageContainer>
       <Card>
-        <Form
-          name="cascade"
-          layout="vertical"
-          form={form}
-          initialValues={{
-            proxyStream: false,
-            sipConfigs: {
-              transport: 'UDP',
-              keepaliveInterval: 60,
-              registerInterval: 3000,
-            },
-          }}
-          onFinish={async (values: any) => {
-            const sipConfigs = {
-              ...values.sipConfigs,
-              remoteAddress: values.sipConfigs.public.host,
-              remotePort: values.sipConfigs.public.port,
-              host: values.sipConfigs.local.host,
-              port: values.sipConfigs.local.port,
-              publicHost: values.sipConfigs.remotePublic.host,
-              publicPort: values.sipConfigs.remotePublic.port,
-            };
-            delete values.sipConfigs;
-            delete sipConfigs.public;
-            delete sipConfigs.local;
-            const param = { ...values, sipConfigs: [sipConfigs] };
-            let resp = undefined;
-            if (id) {
-              resp = await service.update({ ...param, id });
-            } else {
-              resp = await service.save(param);
-            }
-            if (resp && resp.status === 200) {
-              message.success('操作成功!');
-              history.back();
-            }
-          }}
-        >
-          <Row gutter={24}>
-            <TitleComponent data={'基本信息'} />
-            <Col span={12}>
-              <Form.Item
-                label="名称"
-                name="name"
-                rules={[{ required: true, message: '请输入名称' }]}
-              >
-                <Input placeholder="请输入名称" />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label={<span>代理视频流</span>}
-                name="proxyStream"
-                rules={[{ required: true, message: '请选择代理视频流' }]}
-              >
-                <Radio.Group optionType="button" buttonStyle="solid">
-                  <Radio.Button value={true}>启用</Radio.Button>
-                  <Radio.Button value={false}>禁用</Radio.Button>
-                </Radio.Group>
-              </Form.Item>
-            </Col>
-            <TitleComponent data={'信令服务配置'} />
-            <Col span={12}>
-              <Form.Item
-                label={
-                  <span>
-                    集群节点
-                    <Tooltip title="使用此集群节点级联到上级平台">
-                      <QuestionCircleOutlined />
-                    </Tooltip>
-                  </span>
+        <Row gutter={24}>
+          <Col span={12}>
+            <Form
+              name="cascade"
+              layout="vertical"
+              form={form}
+              initialValues={{
+                proxyStream: false,
+                sipConfigs: {
+                  transport: 'UDP',
+                  keepaliveInterval: 60,
+                  registerInterval: 3000,
+                },
+              }}
+              onFinish={async (values: any) => {
+                const sipConfigs = {
+                  ...values.sipConfigs,
+                  remoteAddress: values.sipConfigs.public.host,
+                  remotePort: values.sipConfigs.public.port,
+                  host: values.sipConfigs.local.host,
+                  port: values.sipConfigs.local.port,
+                  publicHost: values.sipConfigs.remotePublic.host,
+                  publicPort: values.sipConfigs.remotePublic.port,
+                };
+                delete values.sipConfigs;
+                delete sipConfigs.public;
+                delete sipConfigs.local;
+                const param = { ...values, sipConfigs: [sipConfigs] };
+                let resp = undefined;
+                if (id) {
+                  resp = await service.update({ ...param, id });
+                } else {
+                  resp = await service.save(param);
                 }
-                name={['sipConfigs', 'clusterNodeId']}
-                rules={[{ required: true, message: '请选择集群节点' }]}
-              >
-                <Select placeholder="请选择集群节点">
-                  {clusters.map((item) => (
-                    <Select.Option key={item.id} value={item.id}>
-                      {item.name}
-                    </Select.Option>
-                  ))}
-                </Select>
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="信令名称"
-                name={['sipConfigs', 'name']}
-                rules={[{ required: true, message: '请输入信令名称' }]}
-              >
-                <Input placeholder="请输入信令名称" />
-              </Form.Item>
-            </Col>
-            <Col span={24}>
-              <Form.Item
-                label="上级SIP ID"
-                name={['sipConfigs', 'sipId']}
-                rules={[{ required: true, message: '请输入上级SIP ID' }]}
-              >
-                <Input placeholder="请输入上级SIP ID" />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="上级SIP域"
-                name={['sipConfigs', 'domain']}
-                rules={[{ required: true, message: '请输入上级平台SIP域' }]}
-              >
-                <Input placeholder="请输入上级平台SIP域" />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="上级SIP 地址"
-                name={['sipConfigs', 'public']}
-                rules={[{ required: true, message: '请输入上级SIP 地址' }, { validator: checkSIP }]}
-              >
-                <SipComponent />
-              </Form.Item>
-            </Col>
-            <Col span={24}>
-              <Form.Item
-                label="本地SIP ID"
-                name={['sipConfigs', 'localSipId']}
-                rules={[{ required: true, message: '请输入网关侧的SIP ID' }]}
-              >
-                <Input placeholder="网关侧的SIP ID" />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label={
-                  <span>
-                    SIP本地地址
-                    <Tooltip title="使用指定的网卡和端口进行请求">
-                      <QuestionCircleOutlined />
-                    </Tooltip>
-                  </span>
+                if (resp && resp.status === 200) {
+                  message.success('操作成功!');
+                  history.back();
                 }
-                name={['sipConfigs', 'local']}
-                rules={[
-                  { required: true, message: '请输入SIP本地地址' },
-                  { validator: checkLocalSIP },
-                ]}
-              >
-                <SipSelectComponent data={list} transport={transport} />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="SIP远程地址"
-                name={['sipConfigs', 'remotePublic']}
-                rules={[{ required: true, message: '请输入SIP远程地址' }, { validator: checkSIP }]}
-              >
-                <SipComponent />
-              </Form.Item>
-            </Col>
-            <Col span={24}>
-              <Form.Item
-                label="传输协议"
-                name={['sipConfigs', 'transport']}
-                rules={[{ required: true, message: '请选择传输协议' }]}
-              >
-                <Radio.Group
-                  optionType="button"
-                  buttonStyle="solid"
-                  onChange={(e) => {
-                    setTransport(e.target.value);
-                  }}
-                >
-                  <Radio.Button value="UDP">UDP</Radio.Button>
-                  <Radio.Button value="TCP">TCP</Radio.Button>
-                </Radio.Group>
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="用户"
-                name={['sipConfigs', 'user']}
-                rules={[{ required: true, message: '请输入用户' }]}
-              >
-                <Input placeholder="请输入用户" />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="接入密码"
-                name={['sipConfigs', 'password']}
-                rules={[{ required: true, message: '请输入接入密码' }]}
-              >
-                <Input.Password placeholder="请输入接入密码" />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="厂商"
-                name={['sipConfigs', 'manufacturer']}
-                rules={[{ required: true, message: '请输入厂商' }]}
-              >
-                <Input placeholder="请输入厂商" />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="型号"
-                name={['sipConfigs', 'model']}
-                rules={[{ required: true, message: '请输入型号' }]}
-              >
-                <Input placeholder="请输入型号" />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="版本号"
-                name={['sipConfigs', 'firmware']}
-                rules={[{ required: true, message: '请输入版本号' }]}
-              >
-                <Input placeholder="请输入版本号" />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="心跳周期(秒)"
-                name={['sipConfigs', 'keepaliveInterval']}
-                rules={[
-                  { required: true, message: '请输入心跳周期' },
-                  { validator: keepValidator },
-                ]}
-              >
-                <InputNumber placeholder="请输入心跳周期" style={{ width: '100%' }} />
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
-                label="注册间隔(秒)"
-                name={['sipConfigs', 'registerInterval']}
-                rules={[
-                  { required: true, message: '请输入注册间隔' },
-                  { validator: keepValidator },
-                ]}
-              >
-                <InputNumber placeholder="请输入注册间隔" style={{ width: '100%' }} />
-              </Form.Item>
-            </Col>
-            <Col span={24}>
-              <Form.Item>
-                <Button type="primary" htmlType="submit">
-                  保存
-                </Button>
-              </Form.Item>
-            </Col>
-          </Row>
-        </Form>
+              }}
+            >
+              <Row gutter={24}>
+                <TitleComponent data={'基本信息'} />
+                <Col span={12}>
+                  <Form.Item
+                    label="名称"
+                    name="name"
+                    rules={[{ required: true, message: '请输入名称' }]}
+                  >
+                    <Input placeholder="请输入名称" />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label={<span>代理视频流</span>}
+                    name="proxyStream"
+                    rules={[{ required: true, message: '请选择代理视频流' }]}
+                  >
+                    <Radio.Group optionType="button" buttonStyle="solid">
+                      <Radio.Button value={true}>启用</Radio.Button>
+                      <Radio.Button value={false}>禁用</Radio.Button>
+                    </Radio.Group>
+                  </Form.Item>
+                </Col>
+                <TitleComponent data={'信令服务配置'} />
+                <Col span={12}>
+                  <Form.Item
+                    label={
+                      <span>
+                        集群节点
+                        <Tooltip title="使用此集群节点级联到上级平台">
+                          <QuestionCircleOutlined />
+                        </Tooltip>
+                      </span>
+                    }
+                    name={['sipConfigs', 'clusterNodeId']}
+                    rules={[{ required: true, message: '请选择集群节点' }]}
+                  >
+                    <Select placeholder="请选择集群节点">
+                      {clusters.map((item) => (
+                        <Select.Option key={item.id} value={item.id}>
+                          {item.name}
+                        </Select.Option>
+                      ))}
+                    </Select>
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="信令名称"
+                    name={['sipConfigs', 'name']}
+                    rules={[{ required: true, message: '请输入信令名称' }]}
+                  >
+                    <Input placeholder="请输入信令名称" />
+                  </Form.Item>
+                </Col>
+                <Col span={24}>
+                  <Form.Item
+                    label="上级SIP ID"
+                    name={['sipConfigs', 'sipId']}
+                    rules={[{ required: true, message: '请输入上级SIP ID' }]}
+                  >
+                    <Input placeholder="请输入上级SIP ID" />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="上级SIP域"
+                    name={['sipConfigs', 'domain']}
+                    rules={[{ required: true, message: '请输入上级平台SIP域' }]}
+                  >
+                    <Input placeholder="请输入上级平台SIP域" />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="上级SIP 地址"
+                    name={['sipConfigs', 'public']}
+                    rules={[
+                      { required: true, message: '请输入上级SIP 地址' },
+                      { validator: checkSIP },
+                    ]}
+                  >
+                    <SipComponent />
+                  </Form.Item>
+                </Col>
+                <Col span={24}>
+                  <Form.Item
+                    label="本地SIP ID"
+                    name={['sipConfigs', 'localSipId']}
+                    rules={[{ required: true, message: '请输入网关侧的SIP ID' }]}
+                  >
+                    <Input placeholder="网关侧的SIP ID" />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label={
+                      <span>
+                        SIP本地地址
+                        <Tooltip title="使用指定的网卡和端口进行请求">
+                          <QuestionCircleOutlined />
+                        </Tooltip>
+                      </span>
+                    }
+                    name={['sipConfigs', 'local']}
+                    rules={[
+                      { required: true, message: '请输入SIP本地地址' },
+                      { validator: checkLocalSIP },
+                    ]}
+                  >
+                    <SipSelectComponent data={list} transport={transport} />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="SIP远程地址"
+                    name={['sipConfigs', 'remotePublic']}
+                    rules={[
+                      { required: true, message: '请输入SIP远程地址' },
+                      { validator: checkSIP },
+                    ]}
+                  >
+                    <SipComponent />
+                  </Form.Item>
+                </Col>
+                <Col span={24}>
+                  <Form.Item
+                    label="传输协议"
+                    name={['sipConfigs', 'transport']}
+                    rules={[{ required: true, message: '请选择传输协议' }]}
+                  >
+                    <Radio.Group
+                      optionType="button"
+                      buttonStyle="solid"
+                      onChange={(e) => {
+                        setTransport(e.target.value);
+                      }}
+                    >
+                      <Radio.Button value="UDP">UDP</Radio.Button>
+                      <Radio.Button value="TCP">TCP</Radio.Button>
+                    </Radio.Group>
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="用户"
+                    name={['sipConfigs', 'user']}
+                    rules={[{ required: true, message: '请输入用户' }]}
+                  >
+                    <Input placeholder="请输入用户" />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="接入密码"
+                    name={['sipConfigs', 'password']}
+                    rules={[{ required: true, message: '请输入接入密码' }]}
+                  >
+                    <Input.Password placeholder="请输入接入密码" />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="厂商"
+                    name={['sipConfigs', 'manufacturer']}
+                    rules={[{ required: true, message: '请输入厂商' }]}
+                  >
+                    <Input placeholder="请输入厂商" />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="型号"
+                    name={['sipConfigs', 'model']}
+                    rules={[{ required: true, message: '请输入型号' }]}
+                  >
+                    <Input placeholder="请输入型号" />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="版本号"
+                    name={['sipConfigs', 'firmware']}
+                    rules={[{ required: true, message: '请输入版本号' }]}
+                  >
+                    <Input placeholder="请输入版本号" />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="心跳周期(秒)"
+                    name={['sipConfigs', 'keepaliveInterval']}
+                    rules={[
+                      { required: true, message: '请输入心跳周期' },
+                      { validator: keepValidator },
+                    ]}
+                  >
+                    <InputNumber placeholder="请输入心跳周期" style={{ width: '100%' }} />
+                  </Form.Item>
+                </Col>
+                <Col span={12}>
+                  <Form.Item
+                    label="注册间隔(秒)"
+                    name={['sipConfigs', 'registerInterval']}
+                    rules={[
+                      { required: true, message: '请输入注册间隔' },
+                      { validator: keepValidator },
+                    ]}
+                  >
+                    <InputNumber placeholder="请输入注册间隔" style={{ width: '100%' }} />
+                  </Form.Item>
+                </Col>
+                <Col span={24}>
+                  <Form.Item>
+                    <Button type="primary" htmlType="submit">
+                      保存
+                    </Button>
+                  </Form.Item>
+                </Col>
+              </Row>
+            </Form>
+          </Col>
+          <Col span={12}>
+            <div className={styles.doc}>
+              <h1>1.概述</h1>
+              <div>配置国标级联,平台可以将已经接入到自身的摄像头共享给第三方调用播放。</div>
+              <div>
+                <Alert
+                  icon={<InfoCircleFilled style={{ fontSize: 16, marginTop: 5 }} />}
+                  description="注:该配置只用于将本平台向上级联至第三方平台,如需第三方平台向上级联至本平台,请在“视频设备”页面新增设备时选择“GB/T28181”接入方式。"
+                  showIcon
+                />
+              </div>
+              <h1>2.配置说明</h1>
+              <div>以下配置说明以将本平台数据级联到LiveGBS平台为例。</div>
+              <h2>1、上级SIP ID</h2>
+              <div>请填写第三方平台中配置的SIP ID。</div>
+              <div className={styles.image}>
+                <Image width="100%" src={img2} />
+              </div>
+              <h2>2、上级SIP 域</h2>
+              <div>请填写第三方平台中配置的SIP ID域。</div>
+              <div className={styles.image}>
+                <Image width="100%" src={img1} />
+              </div>
+              <h2>3、上级SIP 地址</h2>
+              <div>请填写第三方平台中配置的SIP ID地址。</div>
+              <div className={styles.image}>
+                <Image width="100%" src={img3} />
+              </div>
+              <h2>4、本地SIP ID</h2>
+              <div>
+                请填写本地的SIP ID地址。
+                地址由由中心编码(8位)、行业编码(2位)、类型编码(3位)和序号(7位)四个码段共20位十
+                进制数字字符构成。详细规则请参见《GB/T28181-2016》中附录D部分。
+              </div>
+              <h2>5、SIP本地地址</h2>
+              <div>请选择指定的网卡和端口,如有疑问请联系系统运维人员。</div>
+              <h2>6、用户</h2>
+              <div>部分平台有基于用于和接入密码的特殊认证。通常情况下,请填写本地SIP ID值。</div>
+              <h2>7、接入密码</h2>
+              <div>需与上级平台设置的接入密码一致,用于身份认证。</div>
+              <h2>8、厂商/型号/版本号</h2>
+              <div>
+                本平台将以“设备”的身份级联到上级平台,请设置本平台在上级平台中显示的厂商、型号、版本号。
+              </div>
+              <h2>9、心跳周期</h2>
+              <div>需与上级平台设置的心跳周期保持一致,通常默认60秒。</div>
+              <h2>10、注册间隔</h2>
+              <div>
+                若SIP代理通过注册方式校时,其注册过期时间宜设置为小于 SIP代理与 SIP服务器出现1s误
+                差所经过的运行时间。
+              </div>
+            </div>
+          </Col>
+        </Row>
       </Card>
     </PageContainer>
   );

+ 0 - 0
src/pages/media/Cascade/index.tsx


部分文件因文件數量過多而無法顯示