Browse Source

feat(merge): merge xyh

Next xyh
Lind 3 năm trước cách đây
mục cha
commit
62f54dff01

+ 65 - 0
src/components/PermissionButton/index.tsx

@@ -0,0 +1,65 @@
+import { Button, Tooltip, Popconfirm } from 'antd';
+import type { TooltipProps, PopconfirmProps, ButtonProps } from 'antd';
+import usePermissions from '@/hooks/permission';
+import { useCallback } from 'react';
+import { useIntl } from '@@/plugin-locale/localeExports';
+
+interface PermissionButtonProps extends ButtonProps {
+  tooltip?: TooltipProps;
+  popConfirm?: PopconfirmProps;
+  isPermission?: boolean;
+}
+
+/**
+ * 权限按钮
+ * @param props
+ * @example 引入改组件,使用组件内部 usePermission 获取相应权限
+ */
+const PermissionButton = (props: PermissionButtonProps) => {
+  const { tooltip, popConfirm, isPermission, ...buttonProps } = props;
+
+  const _isPermission =
+    'isPermission' in props && props.isPermission
+      ? 'disabled' in buttonProps
+        ? buttonProps.disabled
+        : false
+      : true;
+
+  const intl = useIntl();
+
+  const defaultButton = <Button {...buttonProps} disabled={_isPermission} />;
+
+  const isTooltip = tooltip ? <Tooltip {...tooltip}>{defaultButton}</Tooltip> : null;
+
+  const noPermission = (
+    <Tooltip
+      title={intl.formatMessage({
+        id: 'pages.data.option.noPermission',
+        defaultMessage: '没有权限',
+      })}
+    >
+      {defaultButton}
+    </Tooltip>
+  );
+
+  const init = useCallback(() => {
+    // 如果有权限
+    if (isPermission) {
+      if (popConfirm) {
+        popConfirm.children = tooltip ? isTooltip : defaultButton;
+        return <Popconfirm disabled={!isPermission} {...popConfirm} />;
+      } else if (tooltip && !popConfirm) {
+        return isTooltip;
+      } else {
+        return defaultButton;
+      }
+    }
+    return noPermission;
+  }, [props, isPermission]);
+
+  return <>{init()}</>;
+};
+
+PermissionButton.usePermission = usePermissions;
+
+export default PermissionButton;

+ 32 - 0
src/components/PermissionButton/readme.md

@@ -0,0 +1,32 @@
+## 权限组件 PermissionButton
+
+### Props
+
+- 继承于`ButtonProps`,进行额外拓展
+
+| 名称         | 类型            | 必传 |
+| ------------ | --------------- | ---- |
+| tooltip      | TooltipProps    | 否   |
+| popConfirm   | PopconfirmProps | 否   |
+| isPermission | boolean         | 否   |
+
+import { PermissionButton } from '@/components';
+
+const { permission } = PermissionButton.usePermission('system/Department')
+
+<PermissionButton popConfirm={{
+    title:intl.formatMessage({
+      id: 'pages.system.role.option.delete',
+      defaultMessage: '确定要删除吗',
+    }),
+      onConfirm(){
+      deleteItem(record.id);
+    }
+  }} tooltip={{
+    title: intl.formatMessage({
+      id: 'pages.data.option.delete',
+      defaultMessage: '删除',
+    })
+  }} isPermission={permission.delete}
+
+> 按钮 </PermissionButton>

+ 1 - 0
src/components/index.ts

@@ -7,3 +7,4 @@ export { default as Player } from './Player';
 export { default as ScreenPlayer } from './Player/ScreenPlayer';
 export { default as Modal } from './Modal';
 export { default as AIcon } from './AIcon';
+export { default as PermissionButton } from './PermissionButton';

+ 3 - 4
src/hooks/permission/index.ts

@@ -1,6 +1,6 @@
 import { useEffect, useState } from 'react';
 import { BUTTON_PERMISSION_ENUM } from '@/utils/menu/router';
-import type { MENUS_CODE_TYPE } from '@/utils/menu/router';
+import type { MENUS_CODE_TYPE, BUTTON_PERMISSION } from '@/utils/menu/router';
 import { MENUS_BUTTONS_CACHE } from '@/utils/menu';
 
 type permissionKeyType = keyof typeof BUTTON_PERMISSION_ENUM;
@@ -18,7 +18,7 @@ const usePermissions = (
    * @example getOtherPermission(['add', 'delete']) => boolean
    * @return Boolean
    */
-  getOtherPermission: (permission: string | string[]) => boolean;
+  getOtherPermission: (permission: BUTTON_PERMISSION | BUTTON_PERMISSION[]) => boolean;
 } => {
   const [permission, setPermission] = useState<Partial<permissionType>>({});
 
@@ -52,9 +52,8 @@ const usePermissions = (
 
   useEffect(() => {
     Object.keys(BUTTON_PERMISSION_ENUM).forEach((key) => {
-      permissionButton[key] = getOtherPermission[key];
+      permissionButton[key] = getOtherPermission(key);
     });
-
     setPermission(permissionButton);
   }, [code]);
 

+ 105 - 127
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, Popconfirm, Tooltip } from 'antd';
+import { Badge, Button, Dropdown, Menu, message, Tooltip } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 import { useHistory } from 'umi';
 import {
@@ -25,12 +25,11 @@ import Export from './Export';
 import Import from './Import';
 import Process from './Process';
 import SearchComponent from '@/components/SearchComponent';
-import { ProTableCard } from '@/components';
+import { ProTableCard, PermissionButton } from '@/components';
 import SystemConst from '@/utils/const';
 import Token from '@/utils/token';
 import DeviceCard from '@/components/ProTableCard/CardItems/device';
-
-import { getButtonPermission, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 
 export const statusMap = new Map();
 statusMap.set('在线', 'success');
@@ -67,6 +66,7 @@ const Instance = (props: any) => {
   const [searchParams, setSearchParams] = useState<any>({});
   const [bindKeys, setBindKeys] = useState<any[]>([]);
   const history = useHistory<Record<string, string>>();
+  const { permission } = PermissionButton.usePermission('device/Instance');
   const intl = useIntl();
 
   useEffect(() => {
@@ -106,20 +106,18 @@ const Instance = (props: any) => {
         <EyeOutlined />
       </Tooltip>
     </Button>,
-    <Button
+    <PermissionButton
       type={'link'}
       key={'state'}
       style={{ padding: 0 }}
-      disabled={getButtonPermission('device/Product', ['action'])}
-    >
-      <Popconfirm
-        title={intl.formatMessage({
+      popConfirm={{
+        title: intl.formatMessage({
           id: `pages.data.option.${
             record.state.value !== 'notActive' ? 'disabled' : 'enabled'
           }.tips`,
           defaultMessage: '确认禁用?',
-        })}
-        onConfirm={async () => {
+        }),
+        onConfirm: async () => {
           if (record.state.value !== 'notActive') {
             await service.undeployDevice(record.id);
           } else {
@@ -132,33 +130,31 @@ const Instance = (props: any) => {
             }),
           );
           actionRef.current?.reload();
-        }}
-      >
-        <Tooltip
-          title={intl.formatMessage({
-            id: `pages.data.option.${record.state.value !== 'notActive' ? 'disabled' : 'enabled'}`,
-            defaultMessage: record.state.value !== 'notActive' ? '禁用' : '启用',
-          })}
-        >
-          {record.state.value !== 'notActive' ? <StopOutlined /> : <CheckCircleOutlined />}
-        </Tooltip>
-      </Popconfirm>{' '}
-    </Button>,
-
-    <Button
+        },
+      }}
+      isPermission={permission.action}
+      tooltip={{
+        title: intl.formatMessage({
+          id: `pages.data.option.${record.state.value !== 'notActive' ? 'disabled' : 'enabled'}`,
+          defaultMessage: record.state.value !== 'notActive' ? '禁用' : '启用',
+        }),
+      }}
+    >
+      {record.state.value !== 'notActive' ? <StopOutlined /> : <CheckCircleOutlined />}
+    </PermissionButton>,
+    <PermissionButton
       type={'link'}
       key={'delete'}
       style={{ padding: 0 }}
-      disabled={getButtonPermission('device/Instance', ['delete'])}
-    >
-      <Popconfirm
-        title={intl.formatMessage({
+      isPermission={permission.delete}
+      popConfirm={{
+        title: intl.formatMessage({
           id:
             record.state.value === 'notActive'
               ? 'pages.data.option.remove.tips'
               : 'pages.device.instance.deleteTip',
-        })}
-        onConfirm={async () => {
+        }),
+        onConfirm: async () => {
           if (record.state.value === 'notActive') {
             await service.remove(record.id);
             message.success(
@@ -171,18 +167,11 @@ const Instance = (props: any) => {
           } else {
             message.error(intl.formatMessage({ id: 'pages.device.instance.deleteTip' }));
           }
-        }}
-      >
-        <Tooltip
-          title={intl.formatMessage({
-            id: 'pages.data.option.remove',
-            defaultMessage: '删除',
-          })}
-        >
-          <DeleteOutlined />
-        </Tooltip>
-      </Popconfirm>
-    </Button>,
+        },
+      }}
+    >
+      <DeleteOutlined />
+    </PermissionButton>,
   ];
 
   const columns: ProColumns<DeviceInstance>[] = [
@@ -289,8 +278,8 @@ const Instance = (props: any) => {
   const menu = (
     <Menu>
       <Menu.Item key="1">
-        <Button
-          disabled={getButtonPermission('device/Instance', ['export'])}
+        <PermissionButton
+          isPermission={permission.delete}
           icon={<ExportOutlined />}
           type="default"
           onClick={() => {
@@ -298,44 +287,43 @@ const Instance = (props: any) => {
           }}
         >
           批量导出设备
-        </Button>
+        </PermissionButton>
       </Menu.Item>
       <Menu.Item key="2">
-        <Button
-          disabled={getButtonPermission('device/Instance', ['import'])}
+        <PermissionButton
+          isPermission={permission.import}
           icon={<ImportOutlined />}
           onClick={() => {
             setImportVisible(true);
           }}
         >
           批量导入设备
-        </Button>
+        </PermissionButton>
       </Menu.Item>
       <Menu.Item key="4">
-        <Button
-          disabled={getButtonPermission('device/Instance', ['active'])}
+        <PermissionButton
+          isPermission={permission.active}
           icon={<CheckCircleOutlined />}
           type="primary"
           ghost
-        >
-          <Popconfirm
-            title={'确认激活全部设备?'}
-            onConfirm={() => {
+          popConfirm={{
+            title: '确认激活全部设备?',
+            onConfirm: async () => {
               setType('active');
               const activeAPI = `/${
                 SystemConst.API_BASE
               }/device-instance/deploy?:X_Access_Token=${Token.get()}`;
               setApi(activeAPI);
               setOperationVisible(true);
-            }}
-          >
-            激活全部设备
-          </Popconfirm>
-        </Button>
+            },
+          }}
+        >
+          激活全部设备
+        </PermissionButton>
       </Menu.Item>
       <Menu.Item key="5">
-        <Button
-          disabled={getButtonPermission('device/Instance', ['sync'])}
+        <PermissionButton
+          isPermission={permission.sync}
           icon={<SyncOutlined />}
           type="primary"
           onClick={() => {
@@ -348,58 +336,52 @@ const Instance = (props: any) => {
           }}
         >
           同步设备状态
-        </Button>
+        </PermissionButton>
       </Menu.Item>
       {bindKeys.length > 0 && (
         <Menu.Item key="3">
-          <Button
-            disabled={getButtonPermission('device/Instance', ['delete'])}
+          <PermissionButton
+            isPermission={permission.delete}
             icon={<DeleteOutlined />}
             type="primary"
             danger
-          >
-            <Popconfirm
-              title="确认删除选中设备?"
-              onConfirm={() => {
+            popConfirm={{
+              title: '确认删除选中设备?',
+              onConfirm: () => {
                 service.batchDeleteDevice(bindKeys).then((resp) => {
                   if (resp.status === 200) {
                     message.success('操作成功');
                     actionRef.current?.reset?.();
                   }
                 });
-              }}
-              okText="确认"
-              cancelText="取消"
-            >
-              删除选中设备
-            </Popconfirm>
-          </Button>
+              },
+            }}
+          >
+            删除选中设备
+          </PermissionButton>
         </Menu.Item>
       )}
       {bindKeys.length > 0 && (
         <Menu.Item key="6">
-          <Button
-            disabled={getButtonPermission('device/Instance', ['action'])}
+          <PermissionButton
+            isPermission={permission.action}
             icon={<StopOutlined />}
             type="primary"
             danger
-          >
-            <Popconfirm
-              title="确认禁用选中设备?"
-              onConfirm={() => {
+            popConfirm={{
+              title: '确认禁用选中设备?',
+              onConfirm() {
                 service.batchUndeployDevice(bindKeys).then((resp) => {
                   if (resp.status === 200) {
                     message.success('操作成功');
                     actionRef.current?.reset?.();
                   }
                 });
-              }}
-              okText="确认"
-              cancelText="取消"
-            >
-              禁用选中设备
-            </Popconfirm>
-          </Button>
+              },
+            }}
+          >
+            禁用选中设备
+          </PermissionButton>
         </Menu.Item>
       )}
     </Menu>
@@ -446,13 +428,13 @@ const Instance = (props: any) => {
           },
         }}
         headerTitle={[
-          <Button
+          <PermissionButton
             onClick={() => {
               setVisible(true);
               setCurrent({});
             }}
             style={{ marginRight: 12 }}
-            disabled={getButtonPermission('device/Instance', 'add')}
+            isPermission={permission.add}
             key="button"
             icon={<PlusOutlined />}
             type="primary"
@@ -461,7 +443,7 @@ const Instance = (props: any) => {
               id: 'pages.data.option.add',
               defaultMessage: '新增',
             })}
-          </Button>,
+          </PermissionButton>,
           <Dropdown key={'more'} overlay={menu} placement="bottom">
             <Button>批量操作</Button>
           </Dropdown>,
@@ -482,35 +464,34 @@ const Instance = (props: any) => {
               </div>
             }
             actions={[
-              <Button
+              <PermissionButton
                 type={'link'}
                 onClick={() => {
                   setCurrent(record);
                   setVisible(true);
                 }}
                 key={'edit'}
-                disabled={getButtonPermission('device/Instance', ['update', 'add'])}
+                isPermission={permission.update}
               >
                 <EditOutlined />
                 {intl.formatMessage({
                   id: 'pages.data.option.edit',
                   defaultMessage: '编辑',
                 })}
-              </Button>,
-              <Button
-                disabled={getButtonPermission('device/Instance', ['action'])}
+              </PermissionButton>,
+              <PermissionButton
+                isPermission={permission.action}
                 type={'link'}
                 key={'state'}
                 style={{ padding: 0 }}
-              >
-                <Popconfirm
-                  title={intl.formatMessage({
+                popConfirm={{
+                  title: intl.formatMessage({
                     id: `pages.data.option.${
                       record.state.value !== 'notActive' ? 'disabled' : 'enabled'
                     }.tips`,
                     defaultMessage: '确认禁用?',
-                  })}
-                  onConfirm={async () => {
+                  }),
+                  onConfirm: async () => {
                     if (record.state.value !== 'notActive') {
                       await service.undeployDevice(record.id);
                     } else {
@@ -523,33 +504,30 @@ const Instance = (props: any) => {
                       }),
                     );
                     actionRef.current?.reload();
-                  }}
-                >
-                  {record.state.value !== 'notActive' ? <StopOutlined /> : <CheckCircleOutlined />}
-                  {intl.formatMessage({
-                    id: `pages.data.option.${
-                      record.state.value !== 'notActive' ? 'disabled' : 'enabled'
-                    }`,
-                    defaultMessage: record.state.value !== 'notActive' ? '禁用' : '启用',
-                  })}
-                </Popconfirm>
-              </Button>,
-
-              <Button
+                  },
+                }}
+              >
+                {record.state.value !== 'notActive' ? <StopOutlined /> : <CheckCircleOutlined />}
+                {intl.formatMessage({
+                  id: `pages.data.option.${
+                    record.state.value !== 'notActive' ? 'disabled' : 'enabled'
+                  }`,
+                  defaultMessage: record.state.value !== 'notActive' ? '禁用' : '启用',
+                })}
+              </PermissionButton>,
+              <PermissionButton
                 key="delete"
-                disabled={getButtonPermission('device/Instance', ['delete'])}
+                isPermission={permission.delete}
                 type={'link'}
                 style={{ padding: 0 }}
-              >
-                <Popconfirm
-                  title={intl.formatMessage({
+                popConfirm={{
+                  title: intl.formatMessage({
                     id:
                       record.state.value === 'notActive'
                         ? 'pages.data.option.remove.tips'
                         : 'pages.device.instance.deleteTip',
-                  })}
-                  key={'delete'}
-                  onConfirm={async () => {
+                  }),
+                  onConfirm: async () => {
                     if (record.state.value === 'notActive') {
                       await service.remove(record.id);
                       message.success(
@@ -562,11 +540,11 @@ const Instance = (props: any) => {
                     } else {
                       message.error(intl.formatMessage({ id: 'pages.device.instance.deleteTip' }));
                     }
-                  }}
-                >
-                  <DeleteOutlined />
-                </Popconfirm>
-              </Button>,
+                  },
+                }}
+              >
+                <DeleteOutlined />
+              </PermissionButton>,
             ]}
           />
         )}

+ 130 - 148
src/pages/device/Product/index.tsx

@@ -1,6 +1,6 @@
-import {PageContainer} from '@ant-design/pro-layout';
-import {Badge, Button, message, Popconfirm, Space, Tooltip, Upload} from 'antd';
-import type {ProductItem} from '@/pages/device/Product/typings';
+import { PageContainer } from '@ant-design/pro-layout';
+import { Badge, Button, message, Space, Tooltip, Upload } from 'antd';
+import type { ProductItem } from '@/pages/device/Product/typings';
 import {
   DeleteOutlined,
   DownloadOutlined,
@@ -10,19 +10,18 @@ import {
   StopOutlined,
 } from '@ant-design/icons';
 import Service from '@/pages/device/Product/service';
-import {observer} from '@formily/react';
-import {model} from '@formily/reactive';
-import {useHistory} from 'umi';
-import {useIntl} from '@@/plugin-locale/localeExports';
-import type {ActionType, ProColumns} from '@jetlinks/pro-table';
-import {useEffect, useRef, useState} from 'react';
+import { observer } from '@formily/react';
+import { model } from '@formily/reactive';
+import { useHistory } from 'umi';
+import { useIntl } from '@@/plugin-locale/localeExports';
+import type { ActionType, ProColumns } from '@jetlinks/pro-table';
+import { useEffect, useRef, useState } from 'react';
 import Save from '@/pages/device/Product/Save';
 import SearchComponent from '@/components/SearchComponent';
-import {getButtonPermission, getMenuPathByParams, MENUS_CODE} from '@/utils/menu';
-import {ProTableCard} from '@/components';
+import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { ProTableCard, AIcon, PermissionButton } from '@/components';
 import ProductCard from '@/components/ProTableCard/CardItems/product';
-import {downloadObject} from '@/utils/util';
-import AIcon from '../../../components/AIcon';
+import { downloadObject } from '@/utils/util';
 
 export const service = new Service('device-product');
 export const statusMap = {
@@ -42,6 +41,7 @@ const Product = observer(() => {
   const intl = useIntl();
   const [queryParam, setQueryParam] = useState({});
   const history = useHistory<Record<string, string>>();
+  const { permission } = PermissionButton.usePermission('device/Product');
 
   useEffect(() => {
     if (history) {
@@ -106,7 +106,6 @@ const Product = observer(() => {
 
   const tools = (record: ProductItem) => [
     <Button
-      disabled={getButtonPermission('device/Product', ['view'])}
       type={'link'}
       onClick={() => {
         productModel.current = record;
@@ -124,8 +123,8 @@ const Product = observer(() => {
         <EyeOutlined />
       </Tooltip>
     </Button>,
-    <Button
-      disabled={getButtonPermission('device/Product', ['update'])}
+    <PermissionButton
+      isPermission={permission.update}
       key="warning"
       onClick={() => {
         setCurrent(record);
@@ -133,99 +132,88 @@ const Product = observer(() => {
       }}
       type={'link'}
       style={{ padding: 0 }}
-    >
-      <Tooltip
-        title={intl.formatMessage({
+      tooltip={{
+        title: intl.formatMessage({
           id: 'pages.data.option.edit',
           defaultMessage: '编辑',
-        })}
-        key={'edit'}
-      >
-        <EditOutlined />
-      </Tooltip>
-    </Button>,
-    <Button
-      disabled={getButtonPermission('device/Product', ['export'])}
+        }),
+      }}
+    >
+      <EditOutlined />
+    </PermissionButton>,
+    <PermissionButton
+      isPermission={permission.export}
       type={'link'}
       style={{ padding: 0 }}
-    >
-      <Tooltip
-        title={intl.formatMessage({
+      tooltip={{
+        title: intl.formatMessage({
           id: 'pages.data.option.download',
           defaultMessage: '下载',
-        })}
-        key={'download'}
-      >
-        <DownloadOutlined
-          onClick={async () => {
-            downloadObject(
-              record,
-              intl.formatMessage({
-                id: 'pages.device.product',
-                defaultMessage: '产品',
-              }),
-            );
-            message.success('操作成功');
-          }}
-        />
-      </Tooltip>
-    </Button>,
-    <Popconfirm
-      key={'state'}
-      title={intl.formatMessage({
-        id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}.tips`,
-        defaultMessage: '是否启用?',
-      })}
-      onConfirm={() => {
-        changeDeploy(record.id, record.state ? 'undeploy' : 'deploy');
+        }),
       }}
     >
-      <Button
-        disabled={getButtonPermission('device/Product', ['action'])}
-        style={{ padding: 0 }}
-        type={'link'}
-      >
-        <Tooltip
-          title={intl.formatMessage({
-            id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}`,
-            defaultMessage: record.state ? '禁用' : '启用',
-          })}
-        >
-          {record.state ? <StopOutlined /> : <AIcon type={'icon-fabu'} />}
-        </Tooltip>
-      </Button>
-    </Popconfirm>,
-    <Button
+      <DownloadOutlined
+        onClick={async () => {
+          downloadObject(
+            record,
+            intl.formatMessage({
+              id: 'pages.device.product',
+              defaultMessage: '产品',
+            }),
+          );
+          message.success('操作成功');
+        }}
+      />
+    </PermissionButton>,
+    <PermissionButton
+      popConfirm={{
+        title: intl.formatMessage({
+          id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}.tips`,
+          defaultMessage: '是否启用?',
+        }),
+        onConfirm() {
+          changeDeploy(record.id, record.state ? 'undeploy' : 'deploy');
+        },
+      }}
+      tooltip={{
+        title: intl.formatMessage({
+          id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}`,
+          defaultMessage: record.state ? '禁用' : '启用',
+        }),
+      }}
+      style={{ padding: 0 }}
+      type={'link'}
+      isPermission={permission.action}
+    >
+      {record.state ? <StopOutlined /> : <AIcon type={'icon-fabu'} />}
+    </PermissionButton>,
+    <PermissionButton
       key="unBindUser"
-      disabled={getButtonPermission('device/Product', ['delete'])}
       type={'link'}
       style={{ padding: 0 }}
-    >
-      <Popconfirm
-        key="unBindUser"
-        title={intl.formatMessage({
+      isPermission={permission.delete}
+      popConfirm={{
+        title: intl.formatMessage({
           id: record.state === 1 ? 'pages.device.productDetail.deleteTip' : 'page.table.isDelete',
           defaultMessage: '是否删除?',
-        })}
-        onConfirm={async () => {
+        }),
+        onConfirm: async () => {
           if (record.state === 0) {
             await deleteItem(record.id);
           } else {
             message.error('已发布的产品不能进行删除操作');
           }
-        }}
-      >
-        <Tooltip
-          title={intl.formatMessage({
-            id: 'pages.data.option.remove',
-            defaultMessage: '删除',
-          })}
-          key={'remove'}
-        >
-          <DeleteOutlined />
-        </Tooltip>
-      </Popconfirm>
-    </Button>,
+        },
+      }}
+      tooltip={{
+        title: intl.formatMessage({
+          id: 'pages.data.option.remove',
+          defaultMessage: '删除',
+        }),
+      }}
+    >
+      <DeleteOutlined />
+    </PermissionButton>,
   ];
 
   const columns: ProColumns<ProductItem>[] = [
@@ -353,12 +341,12 @@ const Product = observer(() => {
         search={false}
         pagination={{ pageSize: 10 }}
         headerTitle={[
-          <Button
+          <PermissionButton
             onClick={() => {
               setCurrent(undefined);
               setVisible(true);
             }}
-            disabled={getButtonPermission('device/Product', ['add'])}
+            isPermission={permission.add}
             key="button"
             icon={<PlusOutlined />}
             type="primary"
@@ -367,9 +355,9 @@ const Product = observer(() => {
               id: 'pages.data.option.add',
               defaultMessage: '新增',
             })}
-          </Button>,
+          </PermissionButton>,
           <Upload
-            disabled={getButtonPermission('device/Product', ['import'])}
+            disabled={!permission.import}
             key={'import'}
             showUploadList={false}
             beforeUpload={(file) => {
@@ -402,12 +390,9 @@ const Product = observer(() => {
               return false;
             }}
           >
-            <Button
-              disabled={getButtonPermission('device/Product', ['import'])}
-              style={{ marginLeft: 12 }}
-            >
+            <PermissionButton isPermission={permission.import} style={{ marginLeft: 12 }}>
               导入
-            </Button>
+            </PermissionButton>
           </Upload>,
         ]}
         cardRender={(record) => (
@@ -427,13 +412,13 @@ const Product = observer(() => {
               </div>
             }
             actions={[
-              <Button
+              <PermissionButton
                 key="edit"
                 onClick={() => {
                   setCurrent(record);
                   setVisible(true);
                 }}
-                disabled={getButtonPermission('device/Product', ['update', 'add'])}
+                isPermission={permission.update}
                 type={'link'}
                 style={{ padding: 0 }}
               >
@@ -442,9 +427,9 @@ const Product = observer(() => {
                   id: 'pages.data.option.edit',
                   defaultMessage: '编辑',
                 })}
-              </Button>,
-              <Button
-                disabled={getButtonPermission('device/Product', ['export'])}
+              </PermissionButton>,
+              <PermissionButton
+                isPermission={permission.export}
                 type={'link'}
                 key={'download'}
                 style={{ padding: 0 }}
@@ -465,55 +450,52 @@ const Product = observer(() => {
                   id: 'pages.data.option.download',
                   defaultMessage: '下载',
                 })}
-              </Button>,
-              <Popconfirm
+              </PermissionButton>,
+              <PermissionButton
                 key={'state'}
-                title={intl.formatMessage({
-                  id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}.tips`,
-                  defaultMessage: '是否启用?',
-                })}
-                onConfirm={() => {
-                  changeDeploy(record.id, record.state ? 'undeploy' : 'deploy');
+                popConfirm={{
+                  title: intl.formatMessage({
+                    id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}.tips`,
+                    defaultMessage: '是否启用?',
+                  }),
+                  onConfirm() {
+                    changeDeploy(record.id, record.state ? 'undeploy' : 'deploy');
+                  },
                 }}
+                style={{ padding: 0 }}
+                type={'link'}
+                isPermission={permission.action}
               >
-                <Button
-                  style={{ padding: 0 }}
-                  type={'link'}
-                  disabled={getButtonPermission('device/Product', ['action'])}
-                >
-                  {record.state ? <StopOutlined /> : <AIcon type={'icon-fabu'} />}
-                  {intl.formatMessage({
-                    id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}`,
-                    defaultMessage: record.state ? '禁用' : '启用',
-                  })}
-                </Button>
-              </Popconfirm>,
-              <Popconfirm
-                key="delete"
-                disabled={getButtonPermission('device/Product', ['delete'])}
-                title={intl.formatMessage({
-                  id:
-                    record.state === 1
-                      ? 'pages.device.productDetail.deleteTip'
-                      : 'page.table.isDelete',
-                  defaultMessage: '是否删除?',
+                {record.state ? <StopOutlined /> : <AIcon type={'icon-fabu'} />}
+                {intl.formatMessage({
+                  id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}`,
+                  defaultMessage: record.state ? '禁用' : '启用',
                 })}
-                onConfirm={async () => {
-                  if (record.state === 0) {
-                    await deleteItem(record.id);
-                  } else {
-                    message.error('已发布的产品不能进行删除操作');
-                  }
+              </PermissionButton>,
+              <PermissionButton
+                key="delete"
+                type={'link'}
+                style={{ padding: 0 }}
+                isPermission={permission.delete}
+                popConfirm={{
+                  title: intl.formatMessage({
+                    id:
+                      record.state === 1
+                        ? 'pages.device.productDetail.deleteTip'
+                        : 'page.table.isDelete',
+                    defaultMessage: '是否删除?',
+                  }),
+                  onConfirm: async () => {
+                    if (record.state === 0) {
+                      await deleteItem(record.id);
+                    } else {
+                      message.error('已发布的产品不能进行删除操作');
+                    }
+                  },
                 }}
               >
-                <Button
-                  type={'link'}
-                  style={{ padding: 0 }}
-                  disabled={getButtonPermission('device/Product', ['delete'])}
-                >
-                  <DeleteOutlined />
-                </Button>
-              </Popconfirm>,
+                <DeleteOutlined />
+              </PermissionButton>,
             ]}
           />
         )}

+ 116 - 109
src/pages/media/Device/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 { Button, message, Popconfirm, Tooltip } from 'antd';
+import { Button, message, Tooltip } from 'antd';
 import {
   DeleteOutlined,
   EditOutlined,
@@ -13,12 +13,12 @@ import {
 } from '@ant-design/icons';
 import type { DeviceItem } from '@/pages/media/Device/typings';
 import { useHistory, useIntl } from 'umi';
-import { BadgeStatus, ProTableCard } from '@/components';
+import { BadgeStatus, ProTableCard, PermissionButton } from '@/components';
 import { StatusColorEnum } from '@/components/BadgeStatus';
 import SearchComponent from '@/components/SearchComponent';
 import MediaDevice from '@/components/ProTableCard/CardItems/mediaDevice';
 import {
-  getButtonPermission,
+  // getButtonPermission,
   getMenuPathByCode,
   getMenuPathByParams,
   MENUS_CODE,
@@ -45,6 +45,7 @@ const Device = () => {
   const [current, setCurrent] = useState<DeviceItem>();
   const [queryParam, setQueryParam] = useState({});
   const history = useHistory<Record<string, string>>();
+  const { permission } = PermissionButton.usePermission('media/Device');
 
   /**
    * table 查询参数
@@ -186,40 +187,42 @@ const Device = () => {
       align: 'center',
       width: 200,
       render: (text, record) => [
-        <Tooltip
+        <PermissionButton
           key="edit"
-          title={intl.formatMessage({
-            id: 'pages.data.option.edit',
-            defaultMessage: '编辑',
-          })}
+          tooltip={{
+            title: intl.formatMessage({
+              id: 'pages.data.option.edit',
+              defaultMessage: '编辑',
+            }),
+          }}
+          isPermission={permission.update}
+          style={{ padding: 0 }}
+          type={'link'}
+          onClick={() => {
+            setCurrent(record);
+            setVisible(true);
+          }}
         >
-          <Button
-            disabled={getButtonPermission('media/Device', 'update')}
-            style={{ padding: 0 }}
-            type={'link'}
-            onClick={() => {
-              setCurrent(record);
-              setVisible(true);
-            }}
-          >
-            <EditOutlined />
-          </Button>
-        </Tooltip>,
-        <Tooltip key={'viewChannel'} title="查看通道">
-          <Button
-            style={{ padding: 0 }}
-            type={'link'}
-            onClick={() => {
-              history.push(
-                `${getMenuPathByCode(MENUS_CODE['media/Device/Channel'])}?id=${record.id}&type=${
-                  record.provider
-                }`,
-              );
-            }}
-          >
-            <PartitionOutlined />
-          </Button>
-        </Tooltip>,
+          <EditOutlined />
+        </PermissionButton>,
+        <PermissionButton
+          tooltip={{
+            title: '查看设备',
+          }}
+          style={{ padding: 0 }}
+          type={'link'}
+          onClick={() => {
+            history.push(
+              `${getMenuPathByCode(MENUS_CODE['media/Device/Channel'])}?id=${record.id}&type=${
+                record.provider
+              }`,
+            );
+          }}
+          isPermission={true}
+          key={'view'}
+        >
+          <PartitionOutlined />
+        </PermissionButton>,
         <Tooltip key={'deviceDetail'} title={'查看'}>
           <Button
             style={{ padding: 0 }}
@@ -233,58 +236,52 @@ const Device = () => {
             <EyeOutlined />
           </Button>
         </Tooltip>,
-        <Tooltip
+        <PermissionButton
+          tooltip={{
+            title:
+              record.provider === ProviderValue.FIXED
+                ? '接入方式为固定地址时不支持更新通道'
+                : '更新通道',
+          }}
           key={'updateChannel'}
-          title={
-            record.provider === ProviderValue.FIXED
-              ? '接入方式为固定地址时不支持更新通道'
-              : '更新通道'
-          }
+          isPermission={permission.action}
+          disabled={record.state.value === 'offline' || record.provider === ProviderValue.FIXED}
+          style={{ padding: 0 }}
+          type={'link'}
+          onClick={() => {
+            updateChannel(record.id);
+          }}
         >
-          <Button
-            style={{ padding: 0 }}
-            type={'link'}
-            disabled={
-              getButtonPermission('media/Device', 'action') ||
-              record.state.value === 'offline' ||
-              record.provider === ProviderValue.FIXED
-            }
-            onClick={() => {
-              updateChannel(record.id);
-            }}
-          >
-            <SyncOutlined />
-          </Button>
-        </Tooltip>,
-        <Tooltip key={'updateChannel'} title="删除">
-          <Popconfirm
-            key="delete"
-            title={intl.formatMessage({
+          <SyncOutlined />
+        </PermissionButton>,
+        <PermissionButton
+          key={'delete'}
+          tooltip={{
+            title: '删除',
+          }}
+          popConfirm={{
+            title: intl.formatMessage({
               id:
                 record.state.value === 'offline'
                   ? 'pages.device.productDetail.deleteTip'
                   : 'page.table.isDelete',
               defaultMessage: '是否删除?',
-            })}
-            onConfirm={async () => {
+            }),
+            onConfirm: async () => {
               if (record.state.value !== 'offline') {
                 await deleteItem(record.id);
               } else {
                 message.error('在线设备不能进行删除操作');
               }
-            }}
-          >
-            <Button
-              type={'link'}
-              style={{ padding: 0 }}
-              disabled={
-                getButtonPermission('media/Device', 'delete') || record.state.value !== 'offline'
-              }
-            >
-              <DeleteOutlined />
-            </Button>
-          </Popconfirm>
-        </Tooltip>,
+            },
+          }}
+          type={'link'}
+          style={{ padding: 0 }}
+          isPermission={permission.delete}
+          disabled={record.state.value !== 'offline'}
+        >
+          <DeleteOutlined />
+        </PermissionButton>,
       ],
     },
   ];
@@ -311,7 +308,7 @@ const Device = () => {
         rowKey="id"
         search={false}
         headerTitle={[
-          <Button
+          <PermissionButton
             onClick={() => {
               setCurrent(undefined);
               setVisible(true);
@@ -319,13 +316,13 @@ const Device = () => {
             key="button"
             icon={<PlusOutlined />}
             type="primary"
-            disabled={getButtonPermission('media/Device', 'add')}
+            isPermission={permission.add}
           >
             {intl.formatMessage({
               id: 'pages.data.option.add',
               defaultMessage: '新增',
             })}
-          </Button>,
+          </PermissionButton>,
         ]}
         cardRender={(record) => (
           <MediaDevice
@@ -343,9 +340,9 @@ const Device = () => {
               </div>
             }
             actions={[
-              <Button
+              <PermissionButton
                 key="edit"
-                disabled={getButtonPermission('media/Device', 'update')}
+                isPermission={permission.update}
                 onClick={() => {
                   setCurrent(record);
                   setVisible(true);
@@ -358,7 +355,7 @@ const Device = () => {
                   id: 'pages.data.option.edit',
                   defaultMessage: '编辑',
                 })}
-              </Button>,
+              </PermissionButton>,
               <Button
                 key={'viewChannel'}
                 onClick={() => {
@@ -372,10 +369,23 @@ const Device = () => {
                 <PartitionOutlined />
                 查看通道
               </Button>,
-              <Button
+              <PermissionButton
                 key={'updateChannel'}
+                isPermission={permission.update}
+                tooltip={
+                  record.state.value === 'offline' ||
+                  record.provider === providerType['fixed-media']
+                    ? {
+                        title:
+                          record.provider === providerType['fixed-media']
+                            ? '固定地址无法更新通道'
+                            : record.state.value === 'offline'
+                            ? '设备已离线'
+                            : '',
+                      }
+                    : undefined
+                }
                 disabled={
-                  getButtonPermission('media/Device', 'action') ||
                   record.state.value === 'offline' ||
                   record.provider === providerType['fixed-media']
                 }
@@ -385,35 +395,32 @@ const Device = () => {
               >
                 <SyncOutlined />
                 更新通道
-              </Button>,
-              <Popconfirm
+              </PermissionButton>,
+              <PermissionButton
                 key="delete"
-                title={intl.formatMessage({
-                  id:
-                    record.state.value !== 'offline'
-                      ? 'pages.device.instance.deleteTip'
-                      : 'page.table.isDelete',
-                  defaultMessage: '是否删除?',
-                })}
-                onConfirm={async () => {
-                  if (record.state.value === 'offline') {
-                    await deleteItem(record.id);
-                  } else {
-                    message.error('在线设备不能进行删除操作');
-                  }
+                popConfirm={{
+                  title: intl.formatMessage({
+                    id:
+                      record.state.value !== 'offline'
+                        ? 'pages.device.instance.deleteTip'
+                        : 'page.table.isDelete',
+                    defaultMessage: '是否删除?',
+                  }),
+                  onConfirm: async () => {
+                    if (record.state.value === 'offline') {
+                      await deleteItem(record.id);
+                    } else {
+                      message.error('在线设备不能进行删除操作');
+                    }
+                  },
                 }}
+                type={'link'}
+                style={{ padding: 0 }}
+                isPermission={permission.delete}
+                disabled={record.state.value !== 'offline'}
               >
-                <Button
-                  type={'link'}
-                  style={{ padding: 0 }}
-                  disabled={
-                    getButtonPermission('media/Device', 'delete') ||
-                    record.state.value !== 'offline'
-                  }
-                >
-                  <DeleteOutlined />
-                </Button>
-              </Popconfirm>,
+                <DeleteOutlined />
+              </PermissionButton>,
             ]}
           />
         )}

+ 2 - 13
src/pages/system/Department/Assets/deivce/index.tsx

@@ -12,7 +12,6 @@ import Models from './model';
 import Service from '@/pages/system/Department/Assets/service';
 import Bind from './bind';
 import SearchComponent from '@/components/SearchComponent';
-import { getButtonPermission } from '@/utils/menu';
 
 export const service = new Service<DeviceItem>('assets');
 
@@ -158,13 +157,8 @@ export default observer(() => {
           onConfirm={() => {
             singleUnBind(record.id);
           }}
-          disabled={getButtonPermission('system/Department', ['add', 'update'])}
         >
-          <Button
-            type={'link'}
-            style={{ padding: 0 }}
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
-          >
+          <Button type={'link'} style={{ padding: 0 }}>
             <Tooltip
               title={intl.formatMessage({
                 id: 'pages.system.role.option.unBindUser',
@@ -240,7 +234,6 @@ export default observer(() => {
             icon={<PlusOutlined />}
             type="primary"
             key="bind"
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
           >
             {intl.formatMessage({
               id: 'pages.data.option.assets',
@@ -254,12 +247,8 @@ export default observer(() => {
             })}
             key="unBind"
             onConfirm={handleUnBind}
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
           >
-            <Button
-              icon={<DisconnectOutlined />}
-              disabled={getButtonPermission('system/Department', ['add', 'update'])}
-            >
+            <Button icon={<DisconnectOutlined />}>
               {intl.formatMessage({
                 id: 'pages.system.role.option.unBindUser',
                 defaultMessage: '批量解绑',

+ 2 - 13
src/pages/system/Department/Assets/product/index.tsx

@@ -12,7 +12,6 @@ import Service from '@/pages/system/Department/Assets/service';
 import Models from './model';
 import Bind from './bind';
 import SearchComponent from '@/components/SearchComponent';
-import { getButtonPermission } from '@/utils/menu';
 
 export const service = new Service<ProductItem>('assets');
 
@@ -97,13 +96,8 @@ export default observer(() => {
           onConfirm={() => {
             singleUnBind(record.id);
           }}
-          disabled={getButtonPermission('system/Department', ['add', 'update'])}
         >
-          <Button
-            type={'link'}
-            style={{ padding: 0 }}
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
-          >
+          <Button type={'link'} style={{ padding: 0 }}>
             <Tooltip
               title={intl.formatMessage({
                 id: 'pages.system.role.option.unBindUser',
@@ -179,7 +173,6 @@ export default observer(() => {
             icon={<PlusOutlined />}
             type="primary"
             key="bind"
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
           >
             {intl.formatMessage({
               id: 'pages.data.option.assets',
@@ -193,12 +186,8 @@ export default observer(() => {
             })}
             key="unBind"
             onConfirm={handleUnBind}
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
           >
-            <Button
-              icon={<DisconnectOutlined />}
-              disabled={getButtonPermission('system/Department', ['add', 'update'])}
-            >
+            <Button icon={<DisconnectOutlined />}>
               {intl.formatMessage({
                 id: 'pages.system.role.option.unBindUser',
                 defaultMessage: '批量解绑',

+ 2 - 13
src/pages/system/Department/Assets/productCategory/index.tsx

@@ -13,7 +13,6 @@ import Service from '@/pages/system/Department/Assets/service';
 import Bind from './bind';
 import SearchComponent from '@/components/SearchComponent';
 import { difference } from 'lodash';
-import { getButtonPermission } from '@/utils/menu';
 
 export const service = new Service<ProductCategoryItem>('assets');
 
@@ -117,13 +116,8 @@ export default observer(() => {
           onConfirm={() => {
             singleUnBind(record.id);
           }}
-          disabled={getButtonPermission('system/Department', ['add', 'update'])}
         >
-          <Button
-            type={'link'}
-            style={{ padding: 0 }}
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
-          >
+          <Button type={'link'} style={{ padding: 0 }}>
             <Tooltip
               title={intl.formatMessage({
                 id: 'pages.system.role.option.unBindUser',
@@ -247,7 +241,6 @@ export default observer(() => {
             icon={<PlusOutlined />}
             type="primary"
             key="bind"
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
           >
             {intl.formatMessage({
               id: 'pages.data.option.assets',
@@ -261,12 +254,8 @@ export default observer(() => {
             })}
             key="unBind"
             onConfirm={handleUnBind}
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
           >
-            <Button
-              icon={<DisconnectOutlined />}
-              disabled={getButtonPermission('system/Department', ['add', 'update'])}
-            >
+            <Button icon={<DisconnectOutlined />}>
               {intl.formatMessage({
                 id: 'pages.system.role.option.unBindUser',
                 defaultMessage: '批量解绑',

+ 2 - 13
src/pages/system/Department/Member/index.tsx

@@ -12,7 +12,6 @@ import Service from '@/pages/system/Department/Member/service';
 import { DisconnectOutlined, PlusOutlined } from '@ant-design/icons';
 import Bind from './bind';
 import SearchComponent from '@/components/SearchComponent';
-import { getButtonPermission } from '@/utils/menu';
 
 export const service = new Service('tenant');
 
@@ -130,13 +129,8 @@ const Member = observer(() => {
           onConfirm={() => {
             singleUnBind(record.id);
           }}
-          disabled={getButtonPermission('system/Department', ['add', 'update'])}
         >
-          <Button
-            type={'link'}
-            style={{ padding: 0 }}
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
-          >
+          <Button type={'link'} style={{ padding: 0 }}>
             <Tooltip
               title={intl.formatMessage({
                 id: 'pages.system.role.option.unBindUser',
@@ -198,7 +192,6 @@ const Member = observer(() => {
             icon={<PlusOutlined />}
             type="primary"
             key="bind"
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
           >
             {intl.formatMessage({
               id: 'pages.system.role.option.bindUser',
@@ -212,12 +205,8 @@ const Member = observer(() => {
             })}
             key="unBind"
             onConfirm={handleUnBind}
-            disabled={getButtonPermission('system/Department', ['add', 'update'])}
           >
-            <Button
-              icon={<DisconnectOutlined />}
-              disabled={getButtonPermission('system/Department', ['add', 'update'])}
-            >
+            <Button icon={<DisconnectOutlined />}>
               {intl.formatMessage({
                 id: 'pages.system.role.option.unBindUser',
                 defaultMessage: '批量解绑',

+ 78 - 83
src/pages/system/Department/index.tsx

@@ -5,7 +5,7 @@ import ProTable from '@jetlinks/pro-table';
 import * as React from 'react';
 import { useEffect, useRef, useState } from 'react';
 import { history, useIntl, useLocation } from 'umi';
-import { Button, message, Popconfirm, Tooltip } from 'antd';
+import { message } from 'antd';
 import {
   DeleteOutlined,
   EditOutlined,
@@ -21,8 +21,8 @@ import { observer } from '@formily/react';
 import { model } from '@formily/reactive';
 import Save from './save';
 import SearchComponent from '@/components/SearchComponent';
-import { getButtonPermission, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
-import usePermissions from '@/hooks/permission';
+import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { PermissionButton } from '@/components';
 
 export const service = new Service('organization');
 
@@ -60,13 +60,14 @@ export const getSortIndex = (data: DepartmentItem[], pId?: string): number => {
 
 export default observer(() => {
   const actionRef = useRef<ActionType>();
+  const permissionCode = 'system/Department';
   const intl = useIntl();
   const [param, setParam] = useState({});
   const [expandedRowKeys, setExpandedRowKeys] = useState<React.Key[]>([]);
   const [treeData, setTreeData] = useState<any[]>([]);
   const [sortParam, setSortParam] = useState<any>({ name: 'sortIndex', order: 'asc' });
-  const { permission, getOtherPermission } = usePermissions('system/Department');
   const rowKeys = useRef<React.Key[]>([]);
+  const { permission } = PermissionButton.usePermission(permissionCode);
 
   /**
    * 根据部门ID删除数据
@@ -111,30 +112,35 @@ export default observer(() => {
       valueType: 'option',
       width: 240,
       render: (text, record) => [
-        <Tooltip
-          title={intl.formatMessage({
-            id: permission.update ? 'pages.data.option.edit' : 'pages.data.option.noPermission',
-            defaultMessage: '编辑',
-          })}
+        <PermissionButton
+          key="editable"
+          tooltip={{
+            title: intl.formatMessage({
+              id: 'pages.data.option.edit',
+              defaultMessage: '编辑',
+            }),
+          }}
+          isPermission={permission.update}
+          style={{ padding: 0 }}
+          type="link"
+          onClick={() => {
+            State.current = record;
+            State.visible = true;
+          }}
         >
-          <Button
-            style={{ padding: 0 }}
-            type="link"
-            disabled={!permission.update}
-            key="editable"
-            onClick={() => {
-              State.current = record;
-              State.visible = true;
-            }}
-          >
-            <EditOutlined />
-          </Button>
-        </Tooltip>,
-        <Button
+          <EditOutlined />
+        </PermissionButton>,
+        <PermissionButton
+          key={'addChildren'}
           style={{ padding: 0 }}
+          tooltip={{
+            title: intl.formatMessage({
+              id: 'pages.system.department.option.add',
+              defaultMessage: '新增子部门',
+            }),
+          }}
           type="link"
-          disabled={!getOtherPermission(['add'])}
-          key="editable"
+          isPermission={permission.add}
           onClick={() => {
             State.current = {
               parentId: record.id,
@@ -142,19 +148,19 @@ export default observer(() => {
             State.visible = true;
           }}
         >
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.system.department.option.add',
-              defaultMessage: '新增子部门',
-            })}
-          >
-            <PlusCircleOutlined />
-          </Tooltip>
-        </Button>,
-        <Button
-          type="link"
+          <PlusCircleOutlined />
+        </PermissionButton>,
+        <PermissionButton
+          key={'assets'}
           style={{ padding: 0 }}
-          key="assets"
+          tooltip={{
+            title: intl.formatMessage({
+              id: 'pages.data.option.assets',
+              defaultMessage: '资产分配',
+            }),
+          }}
+          type="link"
+          isPermission={permission.assert}
           onClick={() => {
             history.push(
               `${getMenuPathByParams(
@@ -164,61 +170,50 @@ export default observer(() => {
             );
           }}
         >
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.data.option.assets',
-              defaultMessage: '资产分配',
-            })}
-          >
-            <MedicineBoxOutlined />
-          </Tooltip>
-        </Button>,
-        <Button
+          <MedicineBoxOutlined />
+        </PermissionButton>,
+        <PermissionButton
           type="link"
           key="user"
           style={{ padding: 0 }}
+          tooltip={{
+            title: intl.formatMessage({
+              id: 'pages.system.department.user',
+              defaultMessage: '用户',
+            }),
+          }}
+          isPermission={permission['bind-user']}
           onClick={() =>
             history.push(
               `${getMenuPathByParams(MENUS_CODE['system/Department/Detail'], record.id)}?type=user`,
             )
           }
         >
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.system.department.user',
-              defaultMessage: '用户',
-            })}
-          >
-            <TeamOutlined />
-          </Tooltip>
-        </Button>,
-        <Popconfirm
-          key="unBindUser"
-          title={intl.formatMessage({
-            id: 'pages.system.role.option.delete',
-            defaultMessage: '确定要删除吗',
-          })}
-          onConfirm={() => {
-            deleteItem(record.id);
+          <TeamOutlined />
+        </PermissionButton>,
+        <PermissionButton
+          type="link"
+          key="delete"
+          style={{ padding: 0 }}
+          popConfirm={{
+            title: intl.formatMessage({
+              id: 'pages.system.role.option.delete',
+              defaultMessage: '确定要删除吗',
+            }),
+            onConfirm() {
+              deleteItem(record.id);
+            },
           }}
-          disabled={getButtonPermission('system/Department', ['delete'])}
-        >
-          <Tooltip
-            title={intl.formatMessage({
+          tooltip={{
+            title: intl.formatMessage({
               id: 'pages.data.option.delete',
               defaultMessage: '删除',
-            })}
-          >
-            <Button
-              style={{ padding: 0 }}
-              type="link"
-              disabled={getButtonPermission('system/Department', ['delete'])}
-              key="delete"
-            >
-              <DeleteOutlined />
-            </Button>
-          </Tooltip>
-        </Popconfirm>,
+            }),
+          }}
+          isPermission={permission.delete}
+        >
+          <DeleteOutlined />
+        </PermissionButton>,
       ],
     },
   ];
@@ -355,8 +350,8 @@ export default observer(() => {
         search={false}
         params={param}
         headerTitle={
-          <Button
-            disabled={getButtonPermission('system/Department', ['add'])}
+          <PermissionButton
+            isPermission={permission.add}
             onClick={() => {
               State.visible = true;
             }}
@@ -368,7 +363,7 @@ export default observer(() => {
               id: 'pages.data.option.add',
               defaultMessage: '新增',
             })}
-          </Button>
+          </PermissionButton>
         }
       />
       <Save<DepartmentItem>

+ 34 - 37
src/pages/system/Menu/Detail/buttons.tsx

@@ -1,4 +1,4 @@
-import { Button, Form, Input, message, Modal, Popconfirm, Tooltip } from 'antd';
+import { Button, Form, Input, message, Modal, Tooltip } from 'antd';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { useCallback, useEffect, useState } from 'react';
 import { service } from '@/pages/system/Menu';
@@ -8,7 +8,7 @@ import { DeleteOutlined, EditOutlined, PlusOutlined, SearchOutlined } from '@ant
 import type { MenuButtonInfo, MenuItem } from '@/pages/system/Menu/typing';
 import Permission from '@/pages/system/Menu/components/permission';
 import { useRequest } from '@@/plugin-request/request';
-import { getButtonPermission } from '@/utils/menu';
+import { PermissionButton } from '@/components';
 
 type ButtonsProps = {
   data: MenuItem;
@@ -23,6 +23,7 @@ export default (props: ButtonsProps) => {
   const [visible, setVisible] = useState(false); // Modal显示影藏
   const [id, setId] = useState(''); // 缓存ID
   const [form] = Form.useForm();
+  const { permission } = PermissionButton.usePermission('system/Menu');
 
   const { data: permissions, run: queryPermissions } = useRequest(service.queryPermission, {
     manual: true,
@@ -169,7 +170,7 @@ export default (props: ButtonsProps) => {
       align: 'center',
       width: 240,
       render: (_, record) => [
-        <Button
+        <PermissionButton
           key="edit"
           type={'link'}
           style={{ padding: 0 }}
@@ -179,17 +180,16 @@ export default (props: ButtonsProps) => {
             setDisabled(false);
             setVisible(true);
           }}
-          disabled={getButtonPermission('system/Menu', 'update')}
-        >
-          <Tooltip
-            title={intl.formatMessage({
+          tooltip={{
+            title: intl.formatMessage({
               id: 'pages.data.option.edit',
               defaultMessage: '编辑',
-            })}
-          >
-            <EditOutlined />
-          </Tooltip>
-        </Button>,
+            }),
+          }}
+          isPermission={permission.update}
+        >
+          <EditOutlined />
+        </PermissionButton>,
         <Button
           key="view"
           type={'link'}
@@ -210,32 +210,29 @@ export default (props: ButtonsProps) => {
             <SearchOutlined />
           </Tooltip>
         </Button>,
-        <Popconfirm
+        <PermissionButton
           key="unBindUser"
-          title={intl.formatMessage({
-            id: 'page.system.menu.table.delete',
-            defaultMessage: '是否删除该按钮',
-          })}
-          onConfirm={() => {
-            deleteItem(record.id);
+          type={'link'}
+          style={{ padding: 0 }}
+          popConfirm={{
+            title: intl.formatMessage({
+              id: 'page.system.menu.table.delete',
+              defaultMessage: '是否删除该按钮',
+            }),
+            onConfirm() {
+              deleteItem(record.id);
+            },
           }}
-          disabled={getButtonPermission('system/Menu', 'delete')}
-        >
-          <Tooltip
-            title={intl.formatMessage({
+          tooltip={{
+            title: intl.formatMessage({
               id: 'pages.data.option.delete',
               defaultMessage: '删除',
-            })}
-          >
-            <Button
-              disabled={getButtonPermission('system/Menu', 'delete')}
-              type={'link'}
-              style={{ padding: 0 }}
-            >
-              <DeleteOutlined />
-            </Button>
-          </Tooltip>
-        </Popconfirm>,
+            }),
+          }}
+          isPermission={permission.update}
+        >
+          <DeleteOutlined />
+        </PermissionButton>,
       ],
     },
   ];
@@ -248,7 +245,7 @@ export default (props: ButtonsProps) => {
         search={false}
         pagination={false}
         toolBarRender={() => [
-          <Button
+          <PermissionButton
             onClick={() => {
               if (!props.data) {
                 message.warning('请先新增菜单基本信息');
@@ -260,13 +257,13 @@ export default (props: ButtonsProps) => {
             key="button"
             icon={<PlusOutlined />}
             type="primary"
-            disabled={getButtonPermission('system/Menu', ['add'])}
+            isPermission={permission.update}
           >
             {intl.formatMessage({
               id: 'pages.data.option.add',
               defaultMessage: '新增',
             })}
-          </Button>,
+          </PermissionButton>,
         ]}
       />
       <Modal

+ 6 - 9
src/pages/system/Menu/Detail/edit.tsx

@@ -1,5 +1,4 @@
 import {
-  Button,
   Card,
   Col,
   Form,
@@ -22,7 +21,8 @@ import type { MenuItem } from '@/pages/system/Menu/typing';
 import Title from '../components/Title';
 import Icons from '../components/Icons';
 import { QuestionCircleFilled } from '@ant-design/icons';
-import { getButtonPermission, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { PermissionButton } from '@/components';
 
 type EditProps = {
   data: MenuItem;
@@ -36,6 +36,7 @@ export default (props: EditProps) => {
   const [show] = useState(true);
   const [accessSupport, setAccessSupport] = useState('unsupported');
   const history = useHistory();
+  const { permission } = PermissionButton.usePermission('system/Menu');
 
   const [form] = Form.useForm();
 
@@ -318,7 +319,7 @@ export default (props: EditProps) => {
               </Col>
             </Row>
           )}
-          <Button
+          <PermissionButton
             type="primary"
             onClick={() => {
               if (disabled) {
@@ -327,17 +328,13 @@ export default (props: EditProps) => {
                 saveData();
               }
             }}
-            disabled={
-              disabled
-                ? getButtonPermission('system/Menu', ['update'])
-                : getButtonPermission('system/Menu', ['add'])
-            }
+            isPermission={disabled ? permission.update : permission.add}
           >
             {intl.formatMessage({
               id: `pages.data.option.${disabled ? 'edit' : 'save'}`,
               defaultMessage: '编辑',
             })}
-          </Button>
+          </PermissionButton>
         </Card>
         <Form.Item hidden name={'id'}>
           <Input />

+ 36 - 40
src/pages/system/Menu/index.tsx

@@ -4,7 +4,7 @@ import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
 import { useRef, useState } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
-import { Button, message, Popconfirm, Tooltip } from 'antd';
+import { Button, message, Tooltip } from 'antd';
 import {
   DeleteOutlined,
   PlusCircleOutlined,
@@ -18,7 +18,8 @@ import SearchComponent from '@/components/SearchComponent';
 import Service from './service';
 import type { MenuItem } from './typing';
 import moment from 'moment';
-import { getButtonPermission, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { PermissionButton } from '@/components';
 
 export const service = new Service('menu');
 
@@ -39,8 +40,8 @@ export default observer(() => {
   const intl = useIntl();
 
   const [param, setParam] = useState({});
-  // const [form] = Form.useForm();
   const history = useHistory();
+  const { permission } = PermissionButton.usePermission('system/Menu');
 
   const deleteItem = async (id: string) => {
     const response: any = await service.remove(id);
@@ -149,11 +150,17 @@ export default observer(() => {
             <SearchOutlined />
           </Tooltip>
         </Button>,
-        <Button
+        <PermissionButton
           type="link"
           style={{ padding: 0 }}
           key="editable"
-          disabled={getButtonPermission('system/Menu', ['add'])}
+          isPermission={permission.add}
+          tooltip={{
+            title: intl.formatMessage({
+              id: 'page.system.menu.table.addChildren',
+              defaultMessage: '新增子菜单',
+            }),
+          }}
           onClick={() => {
             State.current = {
               parentId: record.id,
@@ -162,41 +169,30 @@ export default observer(() => {
             pageJump('', record.id, record.url);
           }}
         >
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'page.system.menu.table.addChildren',
-              defaultMessage: '新增子菜单',
-            })}
-          >
-            <PlusCircleOutlined />
-          </Tooltip>
-        </Button>,
-        <Popconfirm
-          key="unBindUser"
-          title={intl.formatMessage({
-            id: 'page.system.menu.table.delete',
-            defaultMessage: '是否删除该菜单',
-          })}
-          onConfirm={() => {
-            deleteItem(record.id);
+          <PlusCircleOutlined />
+        </PermissionButton>,
+        <PermissionButton
+          key="delete"
+          type="link"
+          style={{ padding: 0 }}
+          popConfirm={{
+            title: intl.formatMessage({
+              id: 'page.system.menu.table.delete',
+              defaultMessage: '是否删除该菜单',
+            }),
+            onConfirm() {
+              deleteItem(record.id);
+            },
           }}
-        >
-          <Tooltip
-            title={intl.formatMessage({
+          tooltip={{
+            title: intl.formatMessage({
               id: 'pages.data.option.delete',
               defaultMessage: '删除',
-            })}
-          >
-            <Button
-              type="link"
-              style={{ padding: 0 }}
-              disabled={getButtonPermission('system/Menu', ['delete'])}
-              key="delete"
-            >
-              <DeleteOutlined />
-            </Button>
-          </Tooltip>
-        </Popconfirm>,
+            }),
+          }}
+        >
+          <DeleteOutlined />
+        </PermissionButton>,
       ],
     },
   ];
@@ -266,8 +262,8 @@ export default observer(() => {
           };
         }}
         headerTitle={
-          <Button
-            disabled={getButtonPermission('system/Menu', ['add'])}
+          <PermissionButton
+            isPermission={permission.add}
             onClick={() => {
               pageJump();
             }}
@@ -279,7 +275,7 @@ export default observer(() => {
               id: 'pages.data.option.add',
               defaultMessage: '新增',
             })}
-          </Button>
+          </PermissionButton>
         }
       />
       {/*<Modal*/}

+ 4 - 0
src/utils/menu/router.ts

@@ -115,6 +115,10 @@ export enum BUTTON_PERMISSION_ENUM {
   'update' = 'update',
   'action' = 'action',
   'push' = 'push',
+  'assert' = 'assert',
+  'bind-user' = 'bind-user',
+  'active' = 'active',
+  'sync' = 'sync',
 }
 
 export type BUTTON_PERMISSION = keyof typeof BUTTON_PERMISSION_ENUM | string;