Bladeren bron

feat(merge): merge xyh

fix: bug#4055、4052、4050、4049、4048、4044、4039
Lind 3 jaren geleden
bovenliggende
commit
37b706bb64

+ 53 - 140
src/components/Player/ScreenPlayer.tsx

@@ -1,12 +1,15 @@
 import { useCallback, useEffect, useRef, useState, useImperativeHandle, forwardRef } from 'react';
 import classNames from 'classnames';
 import LivePlayer from './index';
-import { Button, Dropdown, Empty, Input, Menu, Popover, Radio, Tooltip } from 'antd';
+import { Button, Dropdown, Empty, Menu, message, Popconfirm, Popover, Radio, Tooltip } from 'antd';
+import { createSchemaField } from '@formily/react';
+import { Form, FormItem, Input } from '@formily/antd';
 import { useFullscreen } from 'ahooks';
 import './index.less';
 import { DeleteOutlined, QuestionCircleOutlined } from '@ant-design/icons';
 import Service from './service';
 import MediaTool from '@/components/Player/mediaTool';
+import { createForm } from '@formily/core';
 
 type Player = {
   id?: string;
@@ -37,19 +40,27 @@ interface ScreenProps {
 
 const service = new Service();
 
-const DEFAULT_SAVE_CODE = 'screen_save';
+const DEFAULT_SAVE_CODE = 'screen-save';
 
 export default forwardRef((props: ScreenProps, ref) => {
   const [screen, setScreen] = useState(1);
   const [players, setPlayers] = useState<Player[]>([]);
   const [playerActive, setPlayerActive] = useState(0);
   const [historyList, setHistoryList] = useState<any>([]);
-  const [historyTitle, setHistoryTitle] = useState('');
   const [visible, setVisible] = useState(false);
 
   const fullscreenRef = useRef(null);
   const [isFullscreen, { setFull }] = useFullscreen(fullscreenRef);
 
+  const SchemaField = createSchemaField({
+    components: {
+      FormItem,
+      Input,
+    },
+  });
+
+  const historyForm = createForm();
+
   const replaceVideo = useCallback(
     (id: string, channelId: string, url: string) => {
       players[playerActive] = { id, url, channelId, key: 'time_' + new Date().getTime() };
@@ -86,8 +97,9 @@ export default forwardRef((props: ScreenProps, ref) => {
   };
 
   const saveHistory = useCallback(async () => {
+    const historyValue = await historyForm.submit<{ alias: string }>();
     const param = {
-      name: historyTitle,
+      name: historyValue.alias,
       content: JSON.stringify({
         screen: screen,
         players: players,
@@ -97,8 +109,11 @@ export default forwardRef((props: ScreenProps, ref) => {
     if (resp.status === 200) {
       setVisible(false);
       getHistory();
+      message.success('保存成功!');
+    } else {
+      message.error('保存失败');
     }
-  }, [players, historyTitle, screen]);
+  }, [players, screen, historyForm]);
 
   const screenChange = (index: number) => {
     const arr = new Array(index)
@@ -141,11 +156,19 @@ export default forwardRef((props: ScreenProps, ref) => {
               }}
             >
               {item.name}
-              <DeleteOutlined
-                onClick={() => {
-                  deleteHistory(item.id);
+              <Popconfirm
+                title={'确认删除'}
+                onConfirm={(e) => {
+                  e?.stopPropagation();
+                  deleteHistory(item.key);
                 }}
-              />
+              >
+                <DeleteOutlined
+                  onClick={(e) => {
+                    e.stopPropagation();
+                  }}
+                />
+              </Popconfirm>
             </Menu.Item>
           );
         })
@@ -210,11 +233,26 @@ export default forwardRef((props: ScreenProps, ref) => {
               <div className={'screen-tool-save'}>
                 <Popover
                   content={
-                    <div style={{ width: 300 }}>
-                      <Input.TextArea
-                        rows={3}
-                        onChange={(e) => {
-                          setHistoryTitle(e.target.value);
+                    <Form style={{ width: '217px' }} form={historyForm}>
+                      <SchemaField
+                        schema={{
+                          type: 'object',
+                          properties: {
+                            alias: {
+                              'x-decorator': 'FormItem',
+                              'x-component': 'Input.TextArea',
+                              'x-validator': [
+                                {
+                                  max: 64,
+                                  message: '最多可输入64个字符',
+                                },
+                                {
+                                  required: true,
+                                  message: '请输入名称',
+                                },
+                              ],
+                            },
+                          },
                         }}
                       />
                       <Button
@@ -224,7 +262,7 @@ export default forwardRef((props: ScreenProps, ref) => {
                       >
                         保存
                       </Button>
-                    </div>
+                    </Form>
                   }
                   title="分屏名称"
                   trigger="click"
@@ -270,131 +308,6 @@ export default forwardRef((props: ScreenProps, ref) => {
           }
         }}
       />
-      {/*<div className={'live-player-tools'}>*/}
-      {/*  <div className={'direction'}>*/}
-      {/*    <div*/}
-      {/*      className={'direction-item up'}*/}
-      {/*      onMouseDown={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (id && channelId && props.onMouseDown) {*/}
-      {/*          props.onMouseDown(id, channelId, 'UP');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*      onMouseUp={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseUp && id && channelId) {*/}
-      {/*          props.onMouseUp(id, channelId, 'UP');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*    >*/}
-      {/*      <CaretUpOutlined className={'direction-icon'} />*/}
-      {/*    </div>*/}
-      {/*    <div*/}
-      {/*      className={'direction-item right'}*/}
-      {/*      onMouseDown={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseDown && id && channelId) {*/}
-      {/*          props.onMouseDown(id, channelId, 'RIGHT');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*      onMouseUp={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseUp && id && channelId) {*/}
-      {/*          props.onMouseUp(id, channelId, 'RIGHT');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*    >*/}
-      {/*      <CaretRightOutlined className={'direction-icon'} />*/}
-      {/*    </div>*/}
-      {/*    <div*/}
-      {/*      className={'direction-item left'}*/}
-      {/*      onMouseDown={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseDown && id && channelId) {*/}
-      {/*          props.onMouseDown(id, channelId, 'LEFT');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*      onMouseUp={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseUp && id && channelId) {*/}
-      {/*          props.onMouseUp(id, channelId, 'LEFT');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*    >*/}
-      {/*      <CaretLeftOutlined className={'direction-icon'} />*/}
-      {/*    </div>*/}
-      {/*    <div*/}
-      {/*      className={'direction-item down'}*/}
-      {/*      onMouseDown={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseDown && id && channelId) {*/}
-      {/*          props.onMouseDown(id, channelId, 'DOWN');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*      onMouseUp={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseUp && id && channelId) {*/}
-      {/*          props.onMouseUp(id, channelId, 'DOWN');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*    >*/}
-      {/*      <CaretDownOutlined className={'direction-icon'} />*/}
-      {/*    </div>*/}
-      {/*    <div*/}
-      {/*      className={'direction-audio'}*/}
-      {/*      // onMouseDown={() => {*/}
-      {/*      //   const { id, channelId } = players[playerActive];*/}
-      {/*      //   if (props.onMouseDown && id && channelId) {*/}
-      {/*      //     props.onMouseDown(id, channelId, 'AUDIO');*/}
-      {/*      //   }*/}
-      {/*      // }}*/}
-      {/*      // onMouseUp={() => {*/}
-      {/*      //   const { id, channelId } = players[playerActive];*/}
-      {/*      //   if (props.onMouseUp && id && channelId) {*/}
-      {/*      //     props.onMouseUp(id, channelId, 'AUDIO');*/}
-      {/*      //   }*/}
-      {/*      // }}*/}
-      {/*    >*/}
-      {/*      /!*<AudioOutlined />*!/*/}
-      {/*    </div>*/}
-      {/*  </div>*/}
-      {/*  <div className={'zoom'}>*/}
-      {/*    <div*/}
-      {/*      className={'zoom-item zoom-in'}*/}
-      {/*      onMouseDown={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseDown && id && channelId) {*/}
-      {/*          props.onMouseDown(id, channelId, 'ZOOM_IN');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*      onMouseUp={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseUp && id && channelId) {*/}
-      {/*          props.onMouseUp(id, channelId, 'ZOOM_IN');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*    >*/}
-      {/*      <PlusOutlined />*/}
-      {/*    </div>*/}
-      {/*    <div*/}
-      {/*      className={'zoom-item zoom-out'}*/}
-      {/*      onMouseDown={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseDown && id && channelId) {*/}
-      {/*          props.onMouseDown(id, channelId, 'ZOOM_OUT');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*      onMouseUp={() => {*/}
-      {/*        const { id, channelId } = players[playerActive];*/}
-      {/*        if (props.onMouseUp && id && channelId) {*/}
-      {/*          props.onMouseUp(id, channelId, 'ZOOM_OUT');*/}
-      {/*        }*/}
-      {/*      }}*/}
-      {/*    >*/}
-      {/*      <MinusOutlined />*/}
-      {/*    </div>*/}
-      {/*  </div>*/}
-      {/*</div>*/}
     </div>
   );
 });

+ 2 - 1
src/components/ProTableCard/CardItems/mediaDevice.tsx

@@ -8,13 +8,14 @@ import '../index.less';
 export interface ProductCardProps extends DeviceItem {
   detail?: React.ReactNode;
   actions?: React.ReactNode[];
+  showMask?: boolean;
 }
 const defaultImage = require('/public/images/device-media.png');
 
 export default (props: ProductCardProps) => {
   return (
     <TableCard
-      showMask={false}
+      showMask={props.showMask}
       detail={props.detail}
       actions={props.actions}
       status={props.state.value}

+ 4 - 4
src/components/ProTableCard/index.tsx

@@ -63,11 +63,11 @@ const ProTableCard = <
   };
 
   const windowChange = () => {
-    if (window.innerWidth < 1600) {
+    if (window.innerWidth <= 1366) {
+      setColumn(props.gridColumn && props.gridColumn < 2 ? props.gridColumn : 2);
+    } else if (window.innerWidth > 1366 && window.innerWidth <= 1600) {
       setColumn(props.gridColumn && props.gridColumn < 3 ? props.gridColumn : 3);
-    }
-
-    if (window.innerWidth > 1600) {
+    } else if (window.innerWidth > 1600) {
       setColumn(props.gridColumn && props.gridColumn < 4 ? props.gridColumn : 4);
     }
   };

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

@@ -506,8 +506,8 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
                   'x-component': 'Input.TextArea',
                   'x-validator': [
                     {
-                      max: 50,
-                      message: '最多可输入50个字符',
+                      max: 64,
+                      message: '最多可输入64个字符',
                     },
                   ],
                 },

+ 2 - 2
src/locales/zh-CN/pages.ts

@@ -378,9 +378,9 @@ export default {
   'pages.media.config': '基本配置',
   'pages.media.device.transport': '信令传输',
   'pages.media.device.streamMode': '流传输模式',
-  'pages.media.device.channelNumber': '通道数',
+  'pages.media.device.channelNumber': '通道数',
   'pages.media.device.port': '端口',
-  'pages.media.device.manufacturer': '设备厂家',
+  'pages.media.device.manufacturer': '厂商',
   'pages.media.device.model': '型号',
   'pages.media.device.firmware': '固件版本',
   'pages.media.device': '视频设备',

+ 54 - 51
src/pages/device/Product/index.tsx

@@ -170,20 +170,20 @@ const Product = observer(() => {
         />
       </Tooltip>
     </Button>,
-    <Button
-      disabled={getButtonPermission('device/Product', ['action'])}
-      style={{ padding: 0 }}
-      type={'link'}
+    <Popconfirm
+      key={'state'}
+      title={intl.formatMessage({
+        id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}.tips`,
+        defaultMessage: '是否启用?',
+      })}
+      onConfirm={() => {
+        changeDeploy(record.id, record.state ? 'undeploy' : 'deploy');
+      }}
     >
-      <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({
@@ -193,9 +193,10 @@ const Product = observer(() => {
         >
           {record.state ? <StopOutlined /> : <PlayCircleOutlined />}
         </Tooltip>
-      </Popconfirm>
-    </Button>,
+      </Button>
+    </Popconfirm>,
     <Button
+      key="unBindUser"
       disabled={getButtonPermission('device/Product', ['delete'])}
       type={'link'}
       style={{ padding: 0 }}
@@ -280,6 +281,7 @@ const Product = observer(() => {
       <SearchComponent
         field={columns}
         onSearch={searchFn}
+        target="device-produce"
         // onReset={() => {
         //   // 重置分页及搜索参数
         //   actionRef.current?.reset?.();
@@ -424,53 +426,54 @@ const Product = observer(() => {
                   defaultMessage: '下载',
                 })}
               </Button>,
-              <Button
-                style={{ padding: 0 }}
-                type={'link'}
-                disabled={getButtonPermission('device/Product', ['action'])}
+              <Popconfirm
+                key={'state'}
+                title={intl.formatMessage({
+                  id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}.tips`,
+                  defaultMessage: '是否启用?',
+                })}
+                onConfirm={() => {
+                  changeDeploy(record.id, record.state ? 'undeploy' : 'deploy');
+                }}
               >
-                <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
+                  style={{ padding: 0 }}
+                  type={'link'}
+                  disabled={getButtonPermission('device/Product', ['action'])}
                 >
                   {record.state ? <StopOutlined /> : <PlayCircleOutlined />}
                   {intl.formatMessage({
                     id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}`,
                     defaultMessage: record.state ? '禁用' : '启用',
                   })}
-                </Popconfirm>
-              </Button>,
-              <Button
-                type={'link'}
-                style={{ padding: 0 }}
+                </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: '是否删除?',
+                })}
+                onConfirm={async () => {
+                  if (record.state === 0) {
+                    await deleteItem(record.id);
+                  } else {
+                    message.error('已发布的产品不能进行删除操作');
+                  }
+                }}
               >
-                <Popconfirm
-                  key="delete"
-                  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 />
-                </Popconfirm>
-              </Button>,
+                </Button>
+              </Popconfirm>,
             ]}
           />
         )}

+ 2 - 0
src/pages/media/Device/Playback/index.tsx

@@ -65,6 +65,8 @@ export default () => {
         } else {
           setHistoryList(list);
         }
+      } else {
+        setHistoryList([]);
       }
     }
   };

+ 5 - 1
src/pages/media/Device/Save/SaveProduct.tsx

@@ -24,7 +24,10 @@ export default (props: SaveProps) => {
   useEffect(() => {
     if (visible) {
       getProviderList({
-        terms: [{ column: 'provider', value: props.type }],
+        terms: [
+          { column: 'provider', value: props.type },
+          { column: 'state', value: 'enabled' },
+        ],
       });
     }
   }, [visible]);
@@ -45,6 +48,7 @@ export default (props: SaveProps) => {
   const onSubmit = async () => {
     const formData = await form.validateFields();
     if (formData) {
+      formData.deviceType = 'device';
       setLoading(true);
       const resp = await service.saveProduct(formData);
       if (resp.status === 200) {

+ 74 - 14
src/pages/media/Device/index.tsx

@@ -9,6 +9,7 @@ import {
   PlusOutlined,
   SyncOutlined,
   PartitionOutlined,
+  EyeOutlined,
 } from '@ant-design/icons';
 import type { DeviceItem } from '@/pages/media/Device/typings';
 import { useIntl, useHistory } from 'umi';
@@ -16,7 +17,12 @@ import { BadgeStatus, ProTableCard } from '@/components';
 import { StatusColorEnum } from '@/components/BadgeStatus';
 import SearchComponent from '@/components/SearchComponent';
 import MediaDevice from '@/components/ProTableCard/CardItems/mediaDevice';
-import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
+import {
+  getButtonPermission,
+  getMenuPathByCode,
+  getMenuPathByParams,
+  MENUS_CODE,
+} from '@/utils/menu';
 import Service from './service';
 import Save from './Save';
 
@@ -68,6 +74,7 @@ const Device = () => {
   const updateChannel = async (id: string) => {
     const resp = await service.updateChannels(id);
     if (resp.status === 200) {
+      actionRef.current?.reload();
       message.success('通道更新成功');
     } else {
       message.error('通道更新失败');
@@ -97,8 +104,9 @@ const Device = () => {
       dataIndex: 'channelNumber',
       title: intl.formatMessage({
         id: 'pages.media.device.channelNumber',
-        defaultMessage: '通道数',
+        defaultMessage: '通道数',
       }),
+      valueType: 'digit',
     },
     {
       dataIndex: 'manufacturer',
@@ -155,17 +163,22 @@ const Device = () => {
             defaultMessage: '编辑',
           })}
         >
-          <a
+          <Button
+            disabled={getButtonPermission('media/Device', 'update')}
+            style={{ padding: 0 }}
+            type={'link'}
             onClick={() => {
               setCurrent(record);
               setVisible(true);
             }}
           >
             <EditOutlined />
-          </a>
+          </Button>
         </Tooltip>,
         <Tooltip key={'viewChannel'} title="查看通道">
-          <a
+          <Button
+            style={{ padding: 0 }}
+            type={'link'}
             onClick={() => {
               history.push(
                 `${getMenuPathByCode(MENUS_CODE['media/Device/Channel'])}?id=${record.id}&type=${
@@ -175,13 +188,37 @@ const Device = () => {
             }}
           >
             <PartitionOutlined />
-          </a>
+          </Button>
         </Tooltip>,
-        <Tooltip key={'updateChannel'} title="更新通道">
+        <Tooltip key={'deviceDetail'} title={'查看'}>
           <Button
-            style={{ padding: '4px' }}
+            style={{ padding: 0 }}
             type={'link'}
-            disabled={record.state.value === 'offline'}
+            onClick={() => {
+              history.push(
+                `${getMenuPathByParams(MENUS_CODE['device/Instance/Detail'], record.id)}`,
+              );
+            }}
+          >
+            <EyeOutlined />
+          </Button>
+        </Tooltip>,
+        <Tooltip
+          key={'updateChannel'}
+          title={
+            record.provider === providerType['fixed-media']
+              ? '接入方式为固定地址时不支持更新通道'
+              : '更新通道'
+          }
+        >
+          <Button
+            style={{ padding: 0 }}
+            type={'link'}
+            disabled={
+              getButtonPermission('media/Device', 'action') ||
+              record.state.value === 'offline' ||
+              record.provider === providerType['fixed-media']
+            }
             onClick={() => {
               updateChannel(record.id);
             }}
@@ -209,8 +246,10 @@ const Device = () => {
           >
             <Button
               type={'link'}
-              style={{ padding: '4px' }}
-              disabled={record.state.value !== 'offline'}
+              style={{ padding: 0 }}
+              disabled={
+                getButtonPermission('media/Device', 'delete') || record.state.value !== 'offline'
+              }
             >
               <DeleteOutlined />
             </Button>
@@ -222,7 +261,7 @@ const Device = () => {
 
   return (
     <PageContainer>
-      <SearchComponent field={columns} onSearch={searchFn} />
+      <SearchComponent field={columns} onSearch={searchFn} target="media-device" />
       <ProTableCard<DeviceItem>
         columns={columns}
         actionRef={actionRef}
@@ -250,6 +289,7 @@ const Device = () => {
             key="button"
             icon={<PlusOutlined />}
             type="primary"
+            disabled={getButtonPermission('media/Device', 'add')}
           >
             {intl.formatMessage({
               id: 'pages.data.option.add',
@@ -260,9 +300,22 @@ const Device = () => {
         cardRender={(record) => (
           <MediaDevice
             {...record}
+            detail={
+              <div
+                style={{ fontSize: 18, padding: 8 }}
+                onClick={() => {
+                  history.push(
+                    `${getMenuPathByParams(MENUS_CODE['device/Instance/Detail'], record.id)}`,
+                  );
+                }}
+              >
+                <EyeOutlined />
+              </div>
+            }
             actions={[
               <Button
                 key="edit"
+                disabled={getButtonPermission('media/Device', 'update')}
                 onClick={() => {
                   setCurrent(record);
                   setVisible(true);
@@ -291,7 +344,11 @@ const Device = () => {
               </Button>,
               <Button
                 key={'updateChannel'}
-                disabled={record.state.value === 'offline'}
+                disabled={
+                  getButtonPermission('media/Device', 'action') ||
+                  record.state.value === 'offline' ||
+                  record.provider === providerType['fixed-media']
+                }
                 onClick={() => {
                   updateChannel(record.id);
                 }}
@@ -319,7 +376,10 @@ const Device = () => {
                 <Button
                   type={'link'}
                   style={{ padding: 0 }}
-                  disabled={record.state.value !== 'offline'}
+                  disabled={
+                    getButtonPermission('media/Device', 'delete') ||
+                    record.state.value !== 'offline'
+                  }
                 >
                   <DeleteOutlined />
                 </Button>

+ 16 - 6
src/pages/system/Menu/Detail/buttons.tsx

@@ -8,6 +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';
 
 type ButtonsProps = {
   data: MenuItem;
@@ -168,14 +169,17 @@ export default (props: ButtonsProps) => {
       align: 'center',
       width: 240,
       render: (_, record) => [
-        <a
+        <Button
           key="edit"
+          type={'link'}
+          style={{ padding: 0 }}
           onClick={() => {
             form.setFieldsValue(record);
             setId(record.id);
             setDisabled(false);
             setVisible(true);
           }}
+          disabled={getButtonPermission('system/Menu', 'update')}
         >
           <Tooltip
             title={intl.formatMessage({
@@ -185,9 +189,11 @@ export default (props: ButtonsProps) => {
           >
             <EditOutlined />
           </Tooltip>
-        </a>,
-        <a
+        </Button>,
+        <Button
           key="view"
+          type={'link'}
+          style={{ padding: 0 }}
           onClick={() => {
             form.setFieldsValue(record);
             setId(record.id);
@@ -203,7 +209,7 @@ export default (props: ButtonsProps) => {
           >
             <SearchOutlined />
           </Tooltip>
-        </a>,
+        </Button>,
         <Popconfirm
           key="unBindUser"
           title={intl.formatMessage({
@@ -220,9 +226,13 @@ export default (props: ButtonsProps) => {
               defaultMessage: '删除',
             })}
           >
-            <a key="delete">
+            <Button
+              disabled={getButtonPermission('system/Menu', 'delete')}
+              type={'link'}
+              style={{ padding: 0 }}
+            >
               <DeleteOutlined />
-            </a>
+            </Button>
           </Tooltip>
         </Popconfirm>,
       ],

+ 0 - 1
src/pages/system/Menu/index.tsx

@@ -137,7 +137,6 @@ export default observer(() => {
           onClick={() => {
             pageJump(record.id, record.parentId || '');
           }}
-          disabled={getButtonPermission('system/Menu', ['view', 'update'])}
         >
           <Tooltip
             title={intl.formatMessage({