Browse Source

fix: 合并冲突

sun-chaochao 3 years ago
parent
commit
c1aa624e80

+ 2 - 0
src/components/DashBoard/echarts.tsx

@@ -53,6 +53,8 @@ const DefaultOptions = {
   ],
 };
 
+export { echarts };
+
 export default (props: EchartsProps) => {
   const chartsRef = useRef<any>(null);
 

+ 48 - 24
src/components/ProTableCard/CardItems/device.tsx

@@ -5,7 +5,7 @@ import { TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
 import { DisconnectOutlined } from '@ant-design/icons';
-import { Popconfirm } from 'antd';
+import { Popconfirm, Tooltip } from 'antd';
 import { useIntl } from '@@/plugin-locale/localeExports';
 
 export interface DeviceCardProps extends Partial<DeviceInstance> {
@@ -17,6 +17,8 @@ export interface DeviceCardProps extends Partial<DeviceInstance> {
   onClick?: () => void;
   grantedPermissions?: string[];
   onUnBind?: (e: any) => void;
+  showBindBtn?: boolean;
+  cardType?: 'bind' | 'unbind';
 }
 
 const defaultImage = require('/public/images/device-type-3-big.png');
@@ -30,7 +32,7 @@ export const PermissionsMap = {
 export const handlePermissionsMap = (permissions?: string[]) => {
   return permissions && permissions.length
     ? permissions.map((item) => PermissionsMap[item]).toString()
-    : '--';
+    : '';
 };
 
 export const ExtraDeviceCard = (props: DeviceCardProps) => {
@@ -65,34 +67,56 @@ export const ExtraDeviceCard = (props: DeviceCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>{props.name}</span>
+            <span className={'card-item-header-name'}>
+              <Tooltip title={props.name}>
+                <span className={'ellipsis'}>{props.name}</span>
+              </Tooltip>
+            </span>
           </div>
           <div className={'card-item-content-flex'}>
             <div className={'flex-auto'}>
               <label>ID</label>
-              <div className={'ellipsis'}>{props.id || '--'}</div>
-            </div>
-            <div className={'flex-auto'}>
-              <label>资产权限</label>
-              <div className={'ellipsis'}>{handlePermissionsMap(props.grantedPermissions)}</div>
+              <div className={'ellipsis'}>
+                <Tooltip title={props.id}>{props.id || ''}</Tooltip>
+              </div>
             </div>
-            <Popconfirm
-              title={intl.formatMessage({
-                id: 'pages.system.role.option.unBindUser',
-                defaultMessage: '是否解除绑定',
-              })}
-              key="unBind"
-              onConfirm={(e) => {
-                e?.stopPropagation();
-                if (props.onUnBind) {
-                  props.onUnBind(e);
-                }
-              }}
-            >
-              <div className={'flex-button'}>
-                <DisconnectOutlined />
+            {props.cardType === 'bind' ? (
+              <div className={'flex-auto'}>
+                <label>说明</label>
+                <Tooltip title={props.describe}>
+                  <div className={'ellipsis'}>{props.describe}</div>
+                </Tooltip>
+              </div>
+            ) : (
+              <div className={'flex-auto'}>
+                <label>资产权限</label>
+                <div className={'ellipsis'}>
+                  <Tooltip title={handlePermissionsMap(props.grantedPermissions)}>
+                    {handlePermissionsMap(props.grantedPermissions)}
+                  </Tooltip>
+                </div>
               </div>
-            </Popconfirm>
+            )}
+
+            {props.showBindBtn !== false && (
+              <Popconfirm
+                title={intl.formatMessage({
+                  id: 'pages.system.role.option.unBindUser',
+                  defaultMessage: '是否解除绑定',
+                })}
+                key="unBind"
+                onConfirm={(e) => {
+                  e?.stopPropagation();
+                  if (props.onUnBind) {
+                    props.onUnBind(e);
+                  }
+                }}
+              >
+                <div className={'flex-button'}>
+                  <DisconnectOutlined />
+                </div>
+              </Popconfirm>
+            )}
           </div>
         </div>
       </div>

+ 47 - 24
src/components/ProTableCard/CardItems/product.tsx

@@ -5,7 +5,7 @@ import { useIntl } from 'umi';
 import { TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
-import { Popconfirm } from 'antd';
+import { Popconfirm, Tooltip } from 'antd';
 import { DisconnectOutlined } from '@ant-design/icons';
 
 export interface ProductCardProps extends Partial<ProductItem> {
@@ -17,6 +17,8 @@ export interface ProductCardProps extends Partial<ProductItem> {
   onClick?: () => void;
   grantedPermissions?: string[];
   onUnBind?: (e: any) => void;
+  showBindBtn?: boolean;
+  cardType?: 'bind' | 'unbind';
 }
 
 const defaultImage = require('/public/images/device-product.png');
@@ -30,7 +32,7 @@ export const PermissionsMap = {
 export const handlePermissionsMap = (permissions?: string[]) => {
   return permissions && permissions.length
     ? permissions.map((item) => PermissionsMap[item]).toString()
-    : '--';
+    : '';
 };
 
 export const ExtraProductCard = (props: ProductCardProps) => {
@@ -67,7 +69,11 @@ export const ExtraProductCard = (props: ProductCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>{props.name}</span>
+            <span className={'card-item-header-name'}>
+              <Tooltip title={props.name}>
+                <span className={'ellipsis'}>{props.name}</span>
+              </Tooltip>
+            </span>
           </div>
           <div className={'card-item-content-items'} style={{ display: 'flex', gap: 12 }}>
             {props.content}
@@ -75,29 +81,46 @@ export const ExtraProductCard = (props: ProductCardProps) => {
           <div className={'card-item-content-flex'}>
             <div className={'flex-auto'}>
               <label>ID</label>
-              <div className={'ellipsis'}>{props.id || '--'}</div>
-            </div>
-            <div className={'flex-auto'}>
-              <label>资产权限</label>
-              <div className={'ellipsis'}>{handlePermissionsMap(props.grantedPermissions)}</div>
+              <div className={'ellipsis'}>
+                <Tooltip title={props.id}>{props.id || ''}</Tooltip>
+              </div>
             </div>
-            <Popconfirm
-              title={intl.formatMessage({
-                id: 'pages.system.role.option.unBindUser',
-                defaultMessage: '是否解除绑定',
-              })}
-              key="unBind"
-              onConfirm={(e) => {
-                e?.stopPropagation();
-                if (props.onUnBind) {
-                  props.onUnBind(e);
-                }
-              }}
-            >
-              <div className={'flex-button'}>
-                <DisconnectOutlined />
+            {props.cardType === 'bind' ? (
+              <div className={'flex-auto'}>
+                <label>说明</label>
+                <Tooltip title={props.describe}>
+                  <div className={'ellipsis'}>{props.describe}</div>
+                </Tooltip>
+              </div>
+            ) : (
+              <div className={'flex-auto'}>
+                <label>资产权限</label>
+                <div className={'ellipsis'}>
+                  <Tooltip title={handlePermissionsMap(props.grantedPermissions)}>
+                    {handlePermissionsMap(props.grantedPermissions)}
+                  </Tooltip>
+                </div>
               </div>
-            </Popconfirm>
+            )}
+            {props.showBindBtn !== false && (
+              <Popconfirm
+                title={intl.formatMessage({
+                  id: 'pages.system.role.option.unBindUser',
+                  defaultMessage: '是否解除绑定',
+                })}
+                key="unBind"
+                onConfirm={(e) => {
+                  e?.stopPropagation();
+                  if (props.onUnBind) {
+                    props.onUnBind(e);
+                  }
+                }}
+              >
+                <div className={'flex-button'}>
+                  <DisconnectOutlined />
+                </div>
+              </Popconfirm>
+            )}
           </div>
         </div>
       </div>

+ 6 - 3
src/components/ProTableCard/index.less

@@ -58,7 +58,10 @@
           gap: 12px;
 
           .flex-auto {
-            flex: 1 1 auto;
+            display: flex;
+            flex-direction: column;
+            flex-grow: 1;
+            width: 0;
           }
 
           .flex-button {
@@ -78,7 +81,7 @@
           }
 
           .ellipsis {
-            width: 70%;
+            max-width: 70%;
             font-weight: bold;
             font-size: 14px;
           }
@@ -103,7 +106,7 @@
           }
 
           .ellipsis {
-            width: 70%;
+            max-width: 70%;
             font-weight: bold;
             font-size: 14px;
           }

+ 1 - 1
src/global.less

@@ -117,7 +117,7 @@ ol {
 }
 
 .ellipsis {
-  width: 100%;
+  max-width: 100%;
   overflow: hidden;
   white-space: nowrap;
   text-align: left;

+ 0 - 1
src/hooks/document/useDomFullHeight.tsx

@@ -38,7 +38,6 @@ const useDomFullHeight = (target: BasicTarget | string, extraHeight: number = 0)
         entries.forEach((entry) => {
           const bodyClient = document.body.getBoundingClientRect();
           const domClient = entry.target.getBoundingClientRect();
-          console.log(domClient);
           if (domClient.y < 50) {
             setState(100);
           } else {

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

@@ -15,13 +15,13 @@ const Functions = () => {
 
   return (
     <Card className={'device-detail-function'} style={{ minHeight: minHeight }}>
-      {functionList ? (
+      {functionList && functionList.length ? (
         <Tabs>
           <Tabs.TabPane tab={'精简模式'} key={1}>
             <>
               <div style={{ paddingBottom: 12 }}>
                 <ExclamationCircleOutlined style={{ marginRight: 12 }} />
-                精简模式下参数只支持输入框的方式录入
+                精简模式下参数只支持输入框的方式录入
               </div>
               <Tabs tabPosition="left">
                 {functionList &&

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

@@ -216,14 +216,14 @@ const Import = (props: Props) => {
           <span style={{ color: '#f5222d' }}>注</span>
           :导入的物模型会覆盖原来的属性、功能、事件、标签,请谨慎操作。
           <br />
-          物模型格式请参考文档:
-          <a
-            rel="noopener noreferrer"
-            target="_blank"
-            href="http://doc.jetlinks.cn/basics-guide/device-manager.html#%E8%AE%BE%E5%A4%87%E5%9E%8B%E5%8F%B7"
-          >
-            设备型号
-          </a>
+          {/*物模型格式请参考文档:*/}
+          {/*<a*/}
+          {/*  rel="noopener noreferrer"*/}
+          {/*  target="_blank"*/}
+          {/*  href="http://doc.jetlinks.cn/basics-guide/device-manager.html#%E8%AE%BE%E5%A4%87%E5%9E%8B%E5%8F%B7"*/}
+          {/*>*/}
+          {/*  设备型号*/}
+          {/*</a>*/}
         </p>
       </div>
       <Form form={form} layout="vertical">

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

@@ -51,7 +51,7 @@ const Metadata = observer((props: Props) => {
     <div className={'device-detail-metadata'} style={{ position: 'relative', minHeight }}>
       <div className={styles.tips}>
         <InfoCircleOutlined style={{ marginRight: '3px' }} />
-        {InstanceModel.detail?.independentMetadata
+        {InstanceModel.detail?.independentMetadata && props.type === 'device'
           ? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'
           : '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'}
       </div>

+ 1 - 1
src/pages/home/components/Guide.tsx

@@ -36,7 +36,7 @@ const GuideItem = (props: GuideItemProps) => {
   };
 
   return (
-    <div className={'home-guide-item step-bar arrow-2'} onClick={jumpPage}>
+    <div className={'home-guide-item step-bar arrow-2 pointer'} onClick={jumpPage}>
       <div className={'item-english'}>{props.english}</div>
       <div className={'item-title'}>{props.name}</div>
       <div className={`item-index`}>

+ 4 - 1
src/pages/home/components/index.less

@@ -26,7 +26,10 @@
   background: linear-gradient(135.62deg, #f6f7fd 22.27%, rgba(255, 255, 255, 0.86) 91.82%);
   border-radius: 2px;
   box-shadow: 0 4px 18px #efefef;
-  cursor: pointer;
+
+  &.pointer {
+    cursor: pointer;
+  }
 
   .item-english {
     color: #4f4f4f;

+ 14 - 8
src/pages/link/DashBoard/index.less

@@ -1,19 +1,25 @@
 .link-dash-board {
-  background-color: #fff;
-
   .echarts-items {
     position: relative;
     display: flex;
-    gap: 12px;
-    margin: 12px 0;
+    gap: 24px;
+    margin-bottom: 24px;
 
     .echarts-item {
       display: flex;
       flex-grow: 1;
-      align-items: center;
-      justify-content: center;
       width: 0;
-      height: 160px;
+      height: 180px;
+      padding: 16px;
+      background-color: #fff;
+
+      .echarts-item-left {
+        width: 45%;
+      }
+
+      .echarts-item-right {
+        width: 55%;
+      }
 
       .echarts-item-title {
         margin-bottom: 8px;
@@ -23,7 +29,7 @@
 
       .echarts-item-value {
         font-weight: bold;
-        font-size: 18px;
+        font-size: 36px;
       }
     }
   }

+ 317 - 103
src/pages/link/DashBoard/index.tsx

@@ -1,6 +1,6 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import DashBoard from '@/components/DashBoard';
-import { Progress, Radio, Select } from 'antd';
+import { Radio, Select } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 import type { EChartsOption } from 'echarts';
 import { useRequest } from 'umi';
@@ -9,13 +9,143 @@ import moment from 'moment';
 import './index.less';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
 import { map } from 'rxjs/operators';
+import Echarts, { echarts } from '@/components/DashBoard/echarts';
 
 type RefType = {
   getValues: Function;
 };
+type TopEchartsItemNodeType = {
+  value: any;
+  title: string;
+};
 
 const service = new Service('dashboard');
 
+const TopEchartsItemNode = (props: TopEchartsItemNodeType) => {
+  const options = {
+    series: [
+      {
+        type: 'gauge',
+        min: 0,
+        max: 100,
+        startAngle: 200,
+        endAngle: -20,
+        center: ['50%', '65%'],
+        title: {
+          show: false,
+        },
+        axisTick: {
+          distance: -20,
+          lineStyle: {
+            width: 1,
+            color: 'rgba(0,0,0,0.15)',
+          },
+        },
+        splitLine: {
+          distance: -22,
+          length: 9,
+          lineStyle: {
+            width: 1,
+            color: '#000',
+          },
+        },
+        axisLabel: {
+          distance: -18,
+          color: 'auto',
+          fontSize: 12,
+        },
+        pointer: {
+          length: '80%',
+          width: 4,
+          itemStyle: {
+            color: 'auto',
+          },
+        },
+        anchor: {
+          show: true,
+          showAbove: true,
+          size: 20,
+          itemStyle: {
+            borderWidth: 3,
+            borderColor: '#fff',
+            shadowBlur: 20,
+            shadowColor: 'rgba(0, 0, 0, .25)',
+            color: 'auto',
+          },
+        },
+        axisLine: {
+          lineStyle: {
+            width: 10,
+            color: [
+              [0.25, 'rgba(36, 178, 118, 1)'],
+              [
+                0.4,
+                new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: 'rgba(66, 147, 255, 1)',
+                  },
+                  {
+                    offset: 1,
+                    color: 'rgba(36, 178, 118, 1)',
+                  },
+                ]),
+              ],
+              [
+                0.5,
+                new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: 'rgba(250, 178, 71, 1)',
+                  },
+                  {
+                    offset: 1,
+                    color: 'rgba(66, 147, 255, 1)',
+                  },
+                ]),
+              ],
+              [
+                1,
+                new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: 'rgba(250, 178, 71, 1)',
+                  },
+                  {
+                    offset: 1,
+                    color: 'rgba(247, 111, 93, 1)',
+                  },
+                ]),
+              ],
+            ],
+          },
+        },
+        detail: {
+          show: false,
+        },
+        data: [{ value: props.value || 0 }],
+      },
+    ],
+  };
+
+  return (
+    <div className={'echarts-item'}>
+      <div className={'echarts-item-left'}>
+        <div className={'echarts-item-title'}>{props.title}</div>
+        <div className={'echarts-item-value'}>{props.value}%</div>
+      </div>
+      <div className={'echarts-item-right'}>
+        <>
+          {
+            // @ts-ignore
+            <Echarts options={options} />
+          }
+        </>
+      </div>
+    </div>
+  );
+};
+
 export default () => {
   const [networkOptions, setNetworkOptions] = useState<EChartsOption | undefined>(undefined);
   const [cpuOptions, setCpuOptions] = useState<EChartsOption | undefined>(undefined);
@@ -39,11 +169,11 @@ export default () => {
     formatResult: (res) => res.result.map((item: any) => ({ label: item.name, value: item.id })),
   });
 
-  const handleNetworkOptions = (data: Record<string, any>) => {
+  const handleNetworkOptions = (data: Record<string, any>, xAxis: string[]) => {
     setNetworkOptions({
       xAxis: {
         type: 'category',
-        data: Object.keys(data),
+        data: xAxis,
       },
       tooltip: {
         trigger: 'axis',
@@ -52,25 +182,36 @@ export default () => {
         type: 'value',
       },
       grid: {
-        left: '3%',
+        left: '80px',
         right: '2%',
       },
-      series: [
-        {
-          data: Object.values(data),
-          type: 'line',
+      color: ['#979AFF'],
+      series: Object.keys(data).map((key) => ({
+        data: data[key]._data,
+        name: key,
+        type: 'line',
+        smooth: true,
+        areaStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            {
+              offset: 0,
+              color: 'rgba(151, 154, 255, 0)',
+            },
+            {
+              offset: 1,
+              color: 'rgba(151, 154, 255, .24)',
+            },
+          ]),
         },
-      ],
+      })),
     });
   };
 
-  const handleJVMOptions = (data: Record<string, any>) => {
+  const handleJVMOptions = (data: Record<string, any>, xAxis: string[]) => {
     setJvmOptions({
       xAxis: {
         type: 'category',
-        data: Object.keys(data).map((item) => {
-          return moment(Number(item)).format('YYYY-MM-DD HH:mm:ss');
-        }),
+        data: xAxis,
       },
       tooltip: {
         trigger: 'axis',
@@ -79,7 +220,7 @@ export default () => {
         type: 'value',
       },
       grid: {
-        left: '3%',
+        left: '50px',
         right: '2%',
       },
       dataZoom: [
@@ -93,22 +234,33 @@ export default () => {
           end: 10,
         },
       ],
-      series: [
-        {
-          data: Object.values(data),
-          type: 'line',
+      color: ['#60DFC7'],
+      series: Object.keys(data).map((key) => ({
+        data: data[key],
+        name: key,
+        type: 'line',
+        smooth: true,
+        areaStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            {
+              offset: 1,
+              color: 'rgba(96, 223, 199, 0)',
+            },
+            {
+              offset: 0,
+              color: 'rgba(96, 223, 199, .24)',
+            },
+          ]),
         },
-      ],
+      })),
     });
   };
 
-  const handleCpuOptions = (data: Record<string, any>) => {
+  const handleCpuOptions = (data: Record<string, any>, xAxis: string[]) => {
     setCpuOptions({
       xAxis: {
         type: 'category',
-        data: Object.keys(data).map((item) => {
-          return moment(Number(item)).format('YYYY-MM-DD HH:mm:ss');
-        }),
+        data: xAxis,
       },
       tooltip: {
         trigger: 'axis',
@@ -117,7 +269,7 @@ export default () => {
         type: 'value',
       },
       grid: {
-        left: '3%',
+        left: '50px',
         right: '2%',
       },
       dataZoom: [
@@ -131,12 +283,25 @@ export default () => {
           end: 10,
         },
       ],
-      series: [
-        {
-          data: Object.values(data),
-          type: 'line',
+      color: ['#2CB6E0'],
+      series: Object.keys(data).map((key) => ({
+        data: data[key],
+        name: key,
+        type: 'line',
+        smooth: true,
+        areaStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+            {
+              offset: 1,
+              color: 'rgba(44, 182, 224, 0)',
+            },
+            {
+              offset: 0,
+              color: 'rgba(44, 182, 224, .24)',
+            },
+          ]),
         },
-      ],
+      })),
     });
   };
 
@@ -186,29 +351,49 @@ export default () => {
       .then((res) => {
         if (res.status === 200) {
           const _networkOptions = {};
+          const _networkXAxis = new Set<string>();
           const _jvmOptions = {};
+          const _jvmXAxis = new Set<string>();
           const _cpuOptions = {};
+          const _cpuXAxis = new Set<string>();
 
           res.result.forEach((item: any) => {
             const value = item.data.value;
+            const nodeID = item.data.clusterNodeId;
             if (item.group === 'network') {
+              const _data: any[] = [];
               value.forEach((networkItem: any) => {
-                _networkOptions[networkItem.timeString] = networkItem.value;
+                _data.push(Number(networkItem.value).toFixed(2));
+                _networkXAxis.add(networkItem.timeString);
               });
+              _networkOptions[nodeID] = {
+                _data: _networkOptions[nodeID]
+                  ? _networkOptions[nodeID]._data.concat(_data)
+                  : _data,
+              };
             } else if (item.group === 'cpu') {
               const memoryJvmHeapFree = value.memoryJvmHeapFree;
               const memoryJvmHeapTotal = value.memoryJvmHeapTotal;
-              _jvmOptions[value.timestamp] = (
+              const _value = (
                 ((memoryJvmHeapTotal - memoryJvmHeapFree) / memoryJvmHeapTotal) *
                 100
               ).toFixed(2);
+              if (!_jvmOptions[nodeID]) {
+                _jvmOptions[nodeID] = [];
+              }
+              _jvmXAxis.add(moment(value.timestamp).format('YYYY-MM-DD HH:mm:ss'));
+              _jvmOptions[nodeID].push(_value);
             } else {
-              _cpuOptions[value.timestamp] = value.cpuSystemUsage;
+              if (!_cpuOptions[nodeID]) {
+                _cpuOptions[nodeID] = [];
+              }
+              _cpuXAxis.add(moment(value.timestamp).format('YYYY-MM-DD HH:mm:ss'));
+              _cpuOptions[nodeID].push(Number(value.cpuSystemUsage).toFixed(2));
             }
           });
-          handleNetworkOptions(_networkOptions);
-          handleJVMOptions(_jvmOptions);
-          handleCpuOptions(_cpuOptions);
+          handleNetworkOptions(_networkOptions, [..._networkXAxis.keys()]);
+          handleJVMOptions(_jvmOptions, [..._jvmXAxis.keys()]);
+          handleCpuOptions(_cpuOptions, [..._cpuXAxis.keys()]);
         }
       });
   };
@@ -234,14 +419,24 @@ export default () => {
         ])
         .then((res) => {
           if (res.status === 200) {
-            const _options = {};
+            const _networkOptions = {};
+            const _networkXAxis = new Set<string>();
             res.result.forEach((item: any) => {
               const value = item.data.value;
+              const _data: any[] = [];
+              const nodeID = item.data.clusterNodeId;
               value.forEach((networkItem: any) => {
-                _options[networkItem.timeString] = networkItem.value;
+                _data.push(Number(networkItem.value).toFixed(2));
+                _networkXAxis.add(networkItem.timeString);
               });
+
+              _networkOptions[nodeID] = {
+                _data: _networkOptions[nodeID]
+                  ? _networkOptions[nodeID]._data.concat(_data)
+                  : _data,
+              };
             });
-            handleNetworkOptions(_options);
+            handleNetworkOptions(_networkOptions, [..._networkXAxis.keys()]);
           }
         });
     }
@@ -266,12 +461,18 @@ export default () => {
         ])
         .then((res) => {
           if (res.status === 200) {
-            const _options = {};
+            const _cpuOptions = {};
+            const _cpuXAxis = new Set<string>();
             res.result.forEach((item: any) => {
               const value = item.data.value;
-              _options[value.timestamp] = value.cpuSystemUsage;
+              const nodeID = item.data.clusterNodeId;
+              _cpuXAxis.add(moment(value.timestamp).format('YYYY-MM-DD HH:mm:ss'));
+              if (!_cpuOptions[nodeID]) {
+                _cpuOptions[nodeID] = [];
+              }
+              _cpuOptions[nodeID].push(Number(value.cpuSystemUsage).toFixed(2));
             });
-            handleCpuOptions(_options);
+            handleCpuOptions(_cpuOptions, [..._cpuXAxis.keys()]);
           }
         });
     }
@@ -296,17 +497,25 @@ export default () => {
         ])
         .then((res) => {
           if (res.status === 200) {
-            const _options = {};
+            const _jvmOptions = {};
+            const _jvmXAxis = new Set<string>();
             res.result.forEach((item: any) => {
               const value = item.data.value;
               const memoryJvmHeapFree = value.memoryJvmHeapFree;
               const memoryJvmHeapTotal = value.memoryJvmHeapTotal;
-              _options[value.timestamp] = (
+              const nodeID = item.data.clusterNodeId;
+
+              const _value = (
                 ((memoryJvmHeapTotal - memoryJvmHeapFree) / memoryJvmHeapTotal) *
                 100
               ).toFixed(2);
+              if (!_jvmOptions[nodeID]) {
+                _jvmOptions[nodeID] = [];
+              }
+              _jvmXAxis.add(moment(value.timestamp).format('YYYY-MM-DD HH:mm:ss'));
+              _jvmOptions[nodeID].push(_value);
             });
-            handleJVMOptions(_options);
+            handleJVMOptions(_jvmOptions, [..._jvmXAxis.keys()]);
           }
         });
     }
@@ -361,68 +570,73 @@ export default () => {
             onChange={(value) => {
               setServerId(value);
             }}
-            style={{ width: 300 }}
+            style={{ width: 300, marginBottom: 24 }}
           />
         ) : null}
         <div className={'echarts-items'}>
-          <div className={'echarts-item'}>
-            <Progress
-              type="circle"
-              strokeWidth={8}
-              width={160}
-              percent={topValues.cpu}
-              format={(percent) => (
-                <div>
-                  <div className={'echarts-item-title'}>CPU使用率</div>
-                  <div className={'echarts-item-value'}>{percent}%</div>
-                </div>
-              )}
-            />
-          </div>
-          <div className={'echarts-item'}>
-            <Progress
-              type="circle"
-              strokeWidth={8}
-              width={160}
-              percent={topValues.jvm}
-              format={(percent) => (
-                <div>
-                  <div className={'echarts-item-title'}>JVM内存</div>
-                  <div className={'echarts-item-value'}>{percent}%</div>
-                </div>
-              )}
-            />
-          </div>
-          <div className={'echarts-item'}>
-            <Progress
-              type="circle"
-              strokeWidth={8}
-              width={160}
-              percent={topValues.usage}
-              format={(percent) => (
-                <div>
-                  <div className={'echarts-item-title'}>磁盘占用率</div>
-                  <div className={'echarts-item-value'}>{percent}%</div>
-                </div>
-              )}
-            />
-          </div>
-          <div className={'echarts-item'}>
-            <Progress
-              type="circle"
-              strokeWidth={8}
-              width={160}
-              percent={topValues.systemUsage}
-              format={(percent) => (
-                <div>
-                  <div className={'echarts-item-title'}>系统内存</div>
-                  <div className={'echarts-item-value'}>{percent}%</div>
-                </div>
-              )}
-            />
-          </div>
+          <TopEchartsItemNode title={'CPU使用率'} value={topValues.cpu} />
+          <TopEchartsItemNode title={'JVM内存'} value={topValues.jvm} />
+          <TopEchartsItemNode title={'磁盘占用率'} value={topValues.usage} />
+          <TopEchartsItemNode title={'磁盘占用率'} value={topValues.systemUsage} />
+          {/*<div className={'echarts-item'}>*/}
+          {/*  */}
+          {/*  <Progress*/}
+          {/*    type="circle"*/}
+          {/*    strokeWidth={8}*/}
+          {/*    width={160}*/}
+          {/*    percent={topValues.cpu}*/}
+          {/*    format={(percent) => (*/}
+          {/*      <div>*/}
+          {/*        <div className={'echarts-item-title'}>CPU使用率</div>*/}
+          {/*        <div className={'echarts-item-value'}>{percent}%</div>*/}
+          {/*      </div>*/}
+          {/*    )}*/}
+          {/*  />*/}
+          {/*</div>*/}
+          {/*<div className={'echarts-item'}>*/}
+          {/*  <Progress*/}
+          {/*    type="circle"*/}
+          {/*    strokeWidth={8}*/}
+          {/*    width={160}*/}
+          {/*    percent={topValues.jvm}*/}
+          {/*    format={(percent) => (*/}
+          {/*      <div>*/}
+          {/*        <div className={'echarts-item-title'}>JVM内存</div>*/}
+          {/*        <div className={'echarts-item-value'}>{percent}%</div>*/}
+          {/*      </div>*/}
+          {/*    )}*/}
+          {/*  />*/}
+          {/*</div>*/}
+          {/*<div className={'echarts-item'}>*/}
+          {/*  <Progress*/}
+          {/*    type="circle"*/}
+          {/*    strokeWidth={8}*/}
+          {/*    width={160}*/}
+          {/*    percent={topValues.usage}*/}
+          {/*    format={(percent) => (*/}
+          {/*      <div>*/}
+          {/*        <div className={'echarts-item-title'}>磁盘占用率</div>*/}
+          {/*        <div className={'echarts-item-value'}>{percent}%</div>*/}
+          {/*      </div>*/}
+          {/*    )}*/}
+          {/*  />*/}
+          {/*</div>*/}
+          {/*<div className={'echarts-item'}>*/}
+          {/*  <Progress*/}
+          {/*    type="circle"*/}
+          {/*    strokeWidth={8}*/}
+          {/*    width={160}*/}
+          {/*    percent={topValues.systemUsage}*/}
+          {/*    format={(percent) => (*/}
+          {/*      <div>*/}
+          {/*        <div className={'echarts-item-title'}>系统内存</div>*/}
+          {/*        <div className={'echarts-item-value'}>{percent}%</div>*/}
+          {/*      </div>*/}
+          {/*    )}*/}
+          {/*  />*/}
+          {/*</div>*/}
         </div>
-        <div>
+        <div style={{ marginBottom: 24 }}>
           <DashBoard
             title={'网络流量'}
             ref={NETWORKRef}
@@ -444,7 +658,7 @@ export default () => {
             onParamsChange={getNetworkEcharts}
           />
         </div>
-        <div style={{ display: 'flex' }}>
+        <div style={{ display: 'flex', gap: 24 }}>
           <DashBoard
             title={'CPU使用率趋势'}
             closeInitialParams={true}

+ 11 - 0
src/pages/media/Device/Channel/Live/index.tsx

@@ -27,6 +27,17 @@ const LiveFC = (props: LiveProps) => {
   );
 
   useEffect(() => {
+    if (props.channelId && props.deviceId) {
+      //   查询当前视频是否在录像
+      service.ptzIsRecord(props.deviceId, props.channelId).then((res) => {
+        if (res.code === 200) {
+          setIsRecord(res.result ? 2 : 0);
+        }
+      });
+    }
+  }, [props.channelId, props.deviceId]);
+
+  useEffect(() => {
     if (props.visible) {
       mediaStart('mp4');
     }

+ 3 - 2
src/pages/media/Home/index.tsx

@@ -20,6 +20,7 @@ export default () => {
   const dashBoardUrl = getMenuPathByCode('media/DashBoard');
   const deviceUrl = getMenuPathByCode('media/Device');
   const channelUrl = getMenuPathByCode('media/Device/Channel');
+  const cascadeUrl = getMenuPathByCode('media/Cascade');
   const splitScreenUrl = getMenuPathByCode('media/SplitScreen');
 
   const [visible, setVisible] = useState(false);
@@ -83,8 +84,8 @@ export default () => {
       key: 'CASCADE',
       name: '国标级联',
       english: 'GB CASCADE',
-      auth: !!channelUrl,
-      url: channelUrl,
+      auth: !!cascadeUrl,
+      url: cascadeUrl,
     },
   ];
 

+ 7 - 3
src/pages/rule-engine/Scene/Save/components/TimeSelect/index.tsx

@@ -49,7 +49,7 @@ export default (props: TimeSelect) => {
     if (props.value && props.options) {
       if (props.value.length >= props.options.length) {
         setCheckedKeys([...props.value, 'null'].map(String));
-        setCheckedNames([...props.options.map((item) => item.label), '全部']);
+        setCheckedNames([...props.options.map((item) => item.label), '每天']);
       } else {
         setCheckedKeys(props.value.map(String));
         const selectedItems = props.options.filter((item) => {
@@ -65,7 +65,7 @@ export default (props: TimeSelect) => {
 
   const menu = (
     <Menu multiple={true} selectedKeys={checkedKeys} onClick={onclick}>
-      <Menu.Item key={'null'}>全部</Menu.Item>
+      <Menu.Item key={'null'}>每天</Menu.Item>
       {props.options &&
         props.options.map((item) => <Menu.Item key={item.value}>{item.label}</Menu.Item>)}
     </Menu>
@@ -106,7 +106,11 @@ export default (props: TimeSelect) => {
       >
         <div className={'time-select-content ellipsis'}>
           {checkedNames.length ? (
-            checkedNames.toString()
+            checkedKeys.includes('null') ? (
+              '每天'
+            ) : (
+              checkedNames.toString()
+            )
           ) : (
             <span style={{ color: 'rgba(0,0,0,.3)' }}>请选择时间</span>
           )}

+ 3 - 1
src/pages/system/Department/Assets/deivce/bind.tsx

@@ -169,7 +169,9 @@ const Bind = observer((props: Props) => {
         rowKey="id"
         search={false}
         gridColumn={2}
-        cardRender={(record) => <ExtraDeviceCard {...record} />}
+        cardRender={(record) => (
+          <ExtraDeviceCard showBindBtn={false} {...record} cardType={'bind'} />
+        )}
         rowSelection={{
           selectedRowKeys: Models.bindKeys,
           onChange: (selectedRowKeys, selectedRows) => {

+ 7 - 0
src/pages/system/Department/Assets/deivce/index.tsx

@@ -13,6 +13,7 @@ import SearchComponent from '@/components/SearchComponent';
 import { ExtraDeviceCard, handlePermissionsMap } from '@/components/ProTableCard/CardItems/device';
 import { ProTableCard } from '@/components';
 import { onlyMessage } from '@/utils/util';
+import { ASSETS_TABS_ENUM, AssetsModel } from '@/pages/system/Department/Assets';
 
 export const service = new Service<DeviceItem>('assets');
 
@@ -34,6 +35,12 @@ export default observer((props: { parentId: string }) => {
   const actionRef = useRef<ActionType>();
 
   const [searchParam, setSearchParam] = useState({});
+
+  useEffect(() => {
+    if (AssetsModel.tabsIndex === ASSETS_TABS_ENUM.Device && actionRef.current) {
+      actionRef.current.reload();
+    }
+  }, [AssetsModel.tabsIndex]);
   /**
    * 解除资产绑定
    */

+ 31 - 8
src/pages/system/Department/Assets/index.tsx

@@ -5,12 +5,26 @@ import ProductCategory from './productCategory';
 import Product from './product';
 import Device from '@/pages/system/Department/Assets/deivce';
 import Member from '@/pages/system/Department/Member';
+import { model } from '@formily/reactive';
+import { observer } from '@formily/react';
+import { ExclamationCircleOutlined } from '@ant-design/icons';
 
 interface AssetsProps {
   parentId: string;
 }
 
-const Assets = (props: AssetsProps) => {
+export enum ASSETS_TABS_ENUM {
+  'ProductCategory' = 'ProductCategory',
+  'Product' = 'Product',
+  'Device' = 'Device',
+  'User' = 'User',
+}
+
+export const AssetsModel = model<{ tabsIndex: string }>({
+  tabsIndex: ASSETS_TABS_ENUM.ProductCategory,
+});
+
+const Assets = observer((props: AssetsProps) => {
   const intl = useIntl();
 
   // 资产类型
@@ -18,32 +32,41 @@ const Assets = (props: AssetsProps) => {
     {
       intlTitle: '1',
       defaultMessage: '产品分类',
-      key: 'ProductCategory',
+      key: ASSETS_TABS_ENUM.ProductCategory,
       components: ProductCategory,
     },
     {
       intlTitle: '2',
       defaultMessage: '产品',
-      key: 'Product',
+      key: ASSETS_TABS_ENUM.Product,
       components: Product,
     },
     {
       intlTitle: '3',
       defaultMessage: '设备',
-      key: 'Device',
+      key: ASSETS_TABS_ENUM.Device,
       components: Device,
     },
     {
       intlTitle: '4',
       defaultMessage: '用户',
-      key: 'User',
+      key: ASSETS_TABS_ENUM.User,
       components: Member,
     },
   ];
 
   return (
-    <div>
-      <Tabs defaultActiveKey="ProductCategory">
+    <div style={{ position: 'relative' }}>
+      <div style={{ position: 'absolute', top: 12, left: 270 }}>
+        <ExclamationCircleOutlined style={{ marginRight: 12 }} />
+        部门拥有的资产为所有类型资产的并集
+      </div>
+      <Tabs
+        accessKey={AssetsModel.tabsIndex}
+        onChange={(key) => {
+          AssetsModel.tabsIndex = key;
+        }}
+      >
         {TabsArray.map((item) => (
           <Tabs.TabPane
             tab={intl.formatMessage({
@@ -58,6 +81,6 @@ const Assets = (props: AssetsProps) => {
       </Tabs>
     </div>
   );
-};
+});
 
 export default Assets;

+ 3 - 1
src/pages/system/Department/Assets/product/bind.tsx

@@ -130,7 +130,9 @@ const Bind = observer((props: Props) => {
         }}
         request={(params) => service.queryProductList(params)}
         params={searchParam}
-        cardRender={(record) => <ExtraProductCard {...record} />}
+        cardRender={(record) => (
+          <ExtraProductCard showBindBtn={false} {...record} cardType={'bind'} />
+        )}
       />
     </Modal>
   );

+ 7 - 0
src/pages/system/Department/Assets/product/index.tsx

@@ -16,6 +16,7 @@ import {
 } from '@/components/ProTableCard/CardItems/product';
 import { ProTableCard } from '@/components';
 import { onlyMessage } from '@/utils/util';
+import { ASSETS_TABS_ENUM, AssetsModel } from '@/pages/system/Department/Assets';
 
 export const service = new Service<ProductItem>('assets');
 
@@ -25,6 +26,12 @@ export default observer((props: { parentId: string }) => {
 
   const [searchParam, setSearchParam] = useState({});
 
+  useEffect(() => {
+    if (AssetsModel.tabsIndex === ASSETS_TABS_ENUM.Product && actionRef.current) {
+      actionRef.current.reload();
+    }
+  }, [AssetsModel.tabsIndex]);
+
   /**
    * 解除资产绑定
    */

+ 7 - 1
src/pages/system/Department/Assets/productCategory/index.tsx

@@ -13,6 +13,7 @@ import Bind from './bind';
 import SearchComponent from '@/components/SearchComponent';
 import { difference } from 'lodash';
 import { onlyMessage } from '@/utils/util';
+import { AssetsModel, ASSETS_TABS_ENUM } from '@/pages/system/Department/Assets';
 
 export const service = new Service<ProductCategoryItem>('assets');
 
@@ -34,6 +35,12 @@ export default observer((props: { parentId: string }) => {
   const actionRef = useRef<ActionType>();
   const [searchParam, setSearchParam] = useState({});
 
+  useEffect(() => {
+    if (AssetsModel.tabsIndex === ASSETS_TABS_ENUM.ProductCategory && actionRef.current) {
+      actionRef.current.reload();
+    }
+  }, [AssetsModel.tabsIndex]);
+
   /**
    * 解除资产绑定
    */
@@ -238,7 +245,6 @@ export default observer((props: { parentId: string }) => {
           selectedRowKeys: Models.unBindKeys,
           onSelect: (record, selected, selectedRows) => {
             const keys = getTableKeys(selected ? selectedRows : [record]);
-            console.log(record, selected, selectedRows);
             if (selected) {
               const _map = new Map();
               keys.forEach((k) => {

+ 28 - 7
src/pages/system/Department/Tree/tree.tsx

@@ -1,4 +1,4 @@
-import { Button, Input, Tree } from 'antd';
+import { Button, Input, Tooltip, Tree } from 'antd';
 import {
   DeleteOutlined,
   EditOutlined,
@@ -16,6 +16,7 @@ import { ISchema } from '@formily/json-schema';
 import { useLocation } from 'umi';
 import { DepartmentItem } from '@/pages/system/Department/typings';
 import { onlyMessage } from '@/utils/util';
+import classnames from 'classnames';
 
 interface TreeProps {
   onSelect: (id: string) => void;
@@ -50,6 +51,7 @@ export default (props: TreeProps) => {
   const [visible, setVisible] = useState(false);
   const [data, setData] = useState<any>();
   const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
+  const [showToolIndex, setShowToolIndex] = useState('');
   const searchKey = useRef('');
 
   const location = useLocation();
@@ -72,6 +74,9 @@ export default (props: TreeProps) => {
 
     if (resp.status === 200) {
       setTreeData(resp.result);
+      if (resp.result && resp.result.length) {
+        setKeys([resp.result[0].id]);
+      }
     }
   };
 
@@ -220,9 +225,25 @@ export default (props: TreeProps) => {
             }}
             titleRender={(nodeData: any) => {
               return (
-                <div>
-                  <span>{nodeData.name}</span>
-                  <span>
+                <div
+                  className={classnames('tree-node-name')}
+                  onMouseEnter={() => {
+                    setShowToolIndex(nodeData.id);
+                  }}
+                  onMouseLeave={() => {
+                    setShowToolIndex('');
+                  }}
+                >
+                  <span className={'tree-node-name--title'}>
+                    <Tooltip title={nodeData.name}>
+                      <span className={'ellipsis'}>{nodeData.name}</span>
+                    </Tooltip>
+                  </span>
+                  <span
+                    className={classnames('tree-node-name--btn', {
+                      'show-btn': nodeData.id === showToolIndex,
+                    })}
+                  >
                     <PermissionButton
                       key="editable"
                       tooltip={{
@@ -232,7 +253,7 @@ export default (props: TreeProps) => {
                         }),
                       }}
                       isPermission={permission.update}
-                      style={{ padding: '0 0 0 6px' }}
+                      style={{ padding: '0 0 0 10px', height: 24 }}
                       type="link"
                       onClick={(e) => {
                         e.stopPropagation();
@@ -246,7 +267,7 @@ export default (props: TreeProps) => {
                     </PermissionButton>
                     <PermissionButton
                       key={'addChildren'}
-                      style={{ padding: '0 0 0 6px' }}
+                      style={{ padding: '0 0 0 10px', height: 24 }}
                       tooltip={{
                         title: intl.formatMessage({
                           id: 'pages.system.department.option.add',
@@ -269,7 +290,7 @@ export default (props: TreeProps) => {
                     <PermissionButton
                       type="link"
                       key="delete"
-                      style={{ padding: '0 0 0 6px' }}
+                      style={{ padding: '0 0 0 10px', height: 24 }}
                       popConfirm={{
                         title: intl.formatMessage({
                           id: 'pages.system.role.option.delete',

+ 24 - 2
src/pages/system/Department/index.less

@@ -9,7 +9,7 @@
 
     .department-left {
       display: flex;
-      flex-basis: 300px;
+      width: 300px;
       height: 100%;
 
       .border-left {
@@ -41,11 +41,33 @@
       .left-tree-body {
         flex: 1 1 auto;
         overflow-y: auto;
+
+        .tree-node-name {
+          display: flex;
+
+          .tree-node-name--title {
+            display: flex;
+            flex-grow: 1;
+            width: 0;
+          }
+
+          .tree-node-name--btn {
+            width: 80px;
+            opacity: 0;
+            transition: opacity 0.3s;
+
+            &.show-btn {
+              opacity: 1;
+            }
+          }
+        }
       }
     }
 
     .department-right {
-      flex: 1 1 auto;
+      display: flex;
+      flex-grow: 1;
+      width: 0;
       padding-left: 24px;
     }
   }

+ 15 - 9
src/pages/system/Menu/Detail/buttons.tsx

@@ -10,6 +10,7 @@ import Permission from '@/pages/system/Menu/components/permission';
 import { useRequest } from '@@/plugin-request/request';
 import { PermissionButton } from '@/components';
 import { onlyMessage } from '@/utils/util';
+import { debounce } from 'lodash';
 
 type ButtonsProps = {
   data: MenuItem;
@@ -52,15 +53,15 @@ export default (props: ButtonsProps) => {
     setDisabled(false);
   };
 
-  // const filterThree = (e: any) => {
-  //   const _data: any = {
-  //     paging: false,
-  //   };
-  //   if (e.target.value) {
-  //     _data.terms = [{ column: 'name', value: e.target.value }];
-  //   }
-  //   queryPermissions(_data);
-  // };
+  const filterThree = (e: any) => {
+    const _data: any = {
+      paging: false,
+    };
+    if (e.target.value) {
+      _data.terms = [{ column: 'name$like', value: `%${e.target.value}%` }];
+    }
+    queryPermissions(_data);
+  };
 
   /**
    * 更新菜单信息
@@ -338,6 +339,11 @@ export default (props: ButtonsProps) => {
             })}
             required={true}
           >
+            <Input
+              onChange={debounce(filterThree, 500)}
+              style={{ width: 300, marginBottom: 12 }}
+              placeholder={'请输入权限名称'}
+            />
             <Form.Item name="permissions" rules={[{ required: true, message: '请选择权限' }]}>
               <Permission
                 title={intl.formatMessage({

+ 26 - 23
src/pages/system/Menu/Detail/edit.tsx

@@ -5,7 +5,7 @@ import { useEffect, useState } from 'react';
 import { service } from '@/pages/system/Menu';
 import { useHistory, useRequest } from 'umi';
 import type { MenuItem } from '@/pages/system/Menu/typing';
-// import { debounce } from 'lodash';
+import { debounce } from 'lodash';
 import Title from '../components/Title';
 import Icons from '../components/Icons';
 import { QuestionCircleFilled } from '@ant-design/icons';
@@ -91,15 +91,15 @@ export default (props: EditProps) => {
     /* eslint-disable */
   }, []);
 
-  // const filterThree = (e: any) => {
-  //   const _data: any = {
-  //     paging: false,
-  //   };
-  //   if (e.target.value) {
-  //     _data.terms = [{ column: 'name', value: e.target.value }];
-  //   }
-  //   queryPermissions(_data);
-  // };
+  const filterThree = (e: any) => {
+    const _data: any = {
+      paging: false,
+    };
+    if (e.target.value) {
+      _data.terms = [{ column: 'name$like', value: `%${e.target.value}%` }];
+    }
+    queryPermissions(_data);
+  };
 
   useEffect(() => {
     if (form) {
@@ -123,7 +123,7 @@ export default (props: EditProps) => {
         <Card>
           <Title title={'基本信息'} />
           <Row>
-            <Col span={3}>
+            <Col flex={'186px'}>
               <Form.Item
                 name={'icon'}
                 label={'菜单图标'}
@@ -138,7 +138,7 @@ export default (props: EditProps) => {
                 <Icons />
               </Form.Item>
             </Col>
-            <Col span={21}>
+            <Col flex="auto">
               <Row gutter={[24, 0]}>
                 <Col span={12}>
                   <Form.Item
@@ -293,19 +293,22 @@ export default (props: EditProps) => {
                     id: 'page.system.menu.permissions',
                     defaultMessage: '权限',
                   })}
-                  name="permissions"
                 >
-                  {/*<Input disabled={disabled} onChange={debounce(filterThree, 300)} style={{ width: 300 }}/>*/}
-                  {/*<Form.Item name='permissions'>*/}
-                  <Permission
-                    title={intl.formatMessage({
-                      id: 'page.system.menu.permissions.operate',
-                      defaultMessage: '操作权限',
-                    })}
-                    // disabled={disabled}
-                    data={permissions}
+                  <Input
+                    onChange={debounce(filterThree, 500)}
+                    style={{ width: 300, marginBottom: 12 }}
+                    placeholder={'请输入权限名称'}
                   />
-                  {/*</Form.Item>*/}
+                  <Form.Item name="permissions" noStyle>
+                    <Permission
+                      title={intl.formatMessage({
+                        id: 'page.system.menu.permissions.operate',
+                        defaultMessage: '操作权限',
+                      })}
+                      // disabled={disabled}
+                      data={permissions}
+                    />
+                  </Form.Item>
                 </Form.Item>
               </Col>
             </Row>