Explorar el Código

fix(merge): merge xyh

lind hace 3 años
padre
commit
c3cd84ebec

+ 4 - 3
src/components/ProTableCard/CardItems/AccessConfig/index.less

@@ -24,12 +24,13 @@
     .card {
       display: flex;
       flex-direction: column;
-      width: 100%;
+      flex-grow: 1;
+      width: 0;
       margin-left: 20px;
 
       .header {
         .title {
-          width: 70%;
+          width: calc(100% - 70px);
           overflow: hidden;
           font-weight: 700;
           font-size: 18px;
@@ -42,7 +43,7 @@
         }
 
         .desc {
-          width: 70%;
+          width: 100%;
           margin-top: 10px;
           overflow: hidden;
           color: #666;

+ 3 - 3
src/components/ProTableCard/CardItems/AccessConfig/index.tsx

@@ -38,9 +38,9 @@ export default (props: AccessConfigCardProps) => {
         </div>
         <div className="card">
           <div className="header">
-            <div className="title">
-              <Tooltip title={props.name}>{props.name || '--'}</Tooltip>
-            </div>
+            <Tooltip title={props.name}>
+              <div className="title ellipsis">{props.name || '--'}</div>
+            </Tooltip>
             <div className="desc">{props.description || '--'}</div>
           </div>
           <div className="container">

+ 12 - 5
src/components/ProTableCard/CardItems/cascade.tsx

@@ -35,11 +35,18 @@ export default (props: CascadeCardProps) => {
             <span className={'card-item-header-name ellipsis'}>{props.name}</span>
           </div>
           <div>通道数量: {props?.count || 0}</div>
-          <div>
-            <Badge
-              status={props.onlineStatus?.value === 'offline' ? 'error' : 'success'}
-              text={`sip:${props.sipConfigs[0]?.sipId}@${props.sipConfigs[0]?.hostAndPort}`}
-            />
+          <div style={{ display: 'flex', width: '100%' }}>
+            <Badge status={props.onlineStatus?.value === 'offline' ? 'error' : 'success'} />
+            <div
+              style={{
+                width: '90%',
+                overflow: 'hidden',
+                whiteSpace: 'nowrap',
+                textOverflow: 'ellipsis',
+              }}
+            >
+              sip:{props.sipConfigs[0]?.sipId}@{props.sipConfigs[0]?.hostAndPort}
+            </div>
           </div>
         </div>
       </div>

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

@@ -21,8 +21,7 @@ export default (props: RuleInstanceCardProps) => {
       statusText={props.state.text}
       statusNames={{
         started: StatusColorEnum.success,
-        stopped: StatusColorEnum.error,
-        disable: StatusColorEnum.processing,
+        disable: StatusColorEnum.error,
       }}
     >
       <div className={'pro-table-card-item'}>

+ 78 - 84
src/pages/device/Instance/Detail/Config/index.tsx

@@ -71,7 +71,7 @@ const Config = () => {
           </div>
         );
       } else {
-        return <span>{config[item.property]}</span>;
+        return <div>{config[item.property]}</div>;
       }
     } else {
       return '--';
@@ -80,94 +80,88 @@ const Config = () => {
 
   return (
     <div style={{ width: '100%', marginTop: '20px' }} className="config">
-      <Descriptions
-        layout="vertical"
-        title={[
-          <span key={1}>配置</span>,
-          <Space key={2}>
-            <Button
-              type="link"
-              onClick={async () => {
-                setVisible(true);
+      <div style={{ display: 'flex', marginBottom: 20 }}>
+        <div style={{ fontSize: 16, fontWeight: 700 }}>配置</div>
+        <Space>
+          <Button
+            type="link"
+            onClick={async () => {
+              setVisible(true);
+            }}
+          >
+            <EditOutlined />
+            编辑
+          </Button>
+          {InstanceModel.detail.state?.value !== 'notActive' && (
+            <Popconfirm
+              title="确认重新应用该配置?"
+              onConfirm={async () => {
+                const resp = await service.deployDevice(id || '');
+                if (resp.status === 200) {
+                  message.success('操作成功');
+                  getDetail();
+                }
               }}
             >
-              <EditOutlined />
-              编辑
-            </Button>
-            {InstanceModel.detail.state?.value !== 'notActive' && (
-              <Popconfirm
-                title="确认重新应用该配置?"
-                onConfirm={async () => {
-                  const resp = await service.deployDevice(id || '');
-                  if (resp.status === 200) {
-                    message.success('操作成功');
-                    getDetail();
-                  }
-                }}
-              >
-                <Button type="link">
-                  <CheckOutlined />
-                  应用配置
-                </Button>
-                <Tooltip title="修改配置后需重新应用后才能生效。">
-                  <QuestionCircleOutlined />
-                </Tooltip>
-              </Popconfirm>
-            )}
-            {InstanceModel.detail?.aloneConfiguration && (
-              <Popconfirm
-                title="确认恢复默认配置?"
-                onConfirm={async () => {
-                  const resp = await service.configurationReset(id || '');
-                  if (resp.status === 200) {
-                    message.success('恢复默认配置成功');
-                    getDetail();
-                  }
-                }}
+              <Button type="link">
+                <CheckOutlined />
+                应用配置
+              </Button>
+              <Tooltip title="修改配置后需重新应用后才能生效。">
+                <QuestionCircleOutlined />
+              </Tooltip>
+            </Popconfirm>
+          )}
+          {InstanceModel.detail?.aloneConfiguration && (
+            <Popconfirm
+              title="确认恢复默认配置?"
+              onConfirm={async () => {
+                const resp = await service.configurationReset(id || '');
+                if (resp.status === 200) {
+                  message.success('恢复默认配置成功');
+                  getDetail();
+                }
+              }}
+            >
+              <Button type="link">
+                <UndoOutlined />
+                恢复默认
+              </Button>
+              <Tooltip
+                title={`该设备单独编辑过配置信息,点击此将恢复成默认的配置信息,请谨慎操作。`}
               >
-                <Button type="link">
-                  <UndoOutlined />
-                  恢复默认
-                </Button>
-                <Tooltip
-                  title={`该设备单独编辑过配置信息,点击此将恢复成默认的配置信息,请谨慎操作。`}
-                >
-                  <QuestionCircleOutlined />
-                </Tooltip>
-              </Popconfirm>
-            )}
-          </Space>,
-        ]}
-      >
+                <QuestionCircleOutlined />
+              </Tooltip>
+            </Popconfirm>
+          )}
+        </Space>
+      </div>
+      <div style={{ paddingLeft: 10 }}>
         {(metadata || []).map((i) => (
-          <Descriptions.Item key={i.name} label={<h4>{i.name}</h4>} span={3}>
-            <div style={{ width: '100%' }}>
-              <Descriptions column={2} bordered size="small">
-                {(i?.properties || []).map((item: any) => (
-                  <Descriptions.Item
-                    span={1}
-                    label={
-                      item.description ? (
-                        <div>
-                          <span style={{ marginRight: '10px' }}>{item.name}</span>
-                          <Tooltip title={item.description}>
-                            <QuestionCircleOutlined />
-                          </Tooltip>
-                        </div>
-                      ) : (
-                        item.name
-                      )
-                    }
-                    key={item.property}
-                  >
-                    {renderComponent(item)}
-                  </Descriptions.Item>
-                ))}
-              </Descriptions>
-            </div>
-          </Descriptions.Item>
+          <Descriptions size="small" column={3} key={i.name} bordered title={<h4>{i.name}</h4>}>
+            {(i?.properties || []).map((item: any) => (
+              <Descriptions.Item
+                span={1}
+                label={
+                  item?.description ? (
+                    <div>
+                      <span style={{ marginRight: '10px' }}>{item.name}</span>
+                      <Tooltip title={item.description}>
+                        <QuestionCircleOutlined />
+                      </Tooltip>
+                    </div>
+                  ) : (
+                    item.name
+                  )
+                }
+                key={item.property}
+              >
+                {renderComponent(item)}
+              </Descriptions.Item>
+            ))}
+          </Descriptions>
         ))}
-      </Descriptions>
+      </div>
       {visible && (
         <Edit
           metadata={metadata || []}

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

@@ -1,7 +1,7 @@
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
 import type { LogItem } from '@/pages/device/Instance/Detail/Log/typings';
-import { Card, Modal, Tooltip } from 'antd';
+import { Card, Input, Modal, Tooltip } from 'antd';
 import { SearchOutlined } from '@ant-design/icons';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { InstanceModel, service } from '@/pages/device/Instance';
@@ -70,7 +70,13 @@ const Log = () => {
         return [
           <a
             key="editable"
-            onClick={() => Modal.info({ title: '详细信息', content: <pre>{content}</pre> })}
+            onClick={() =>
+              Modal.info({
+                title: '详细信息',
+                width: 700,
+                content: <Input.TextArea bordered={false} rows={15} value={content} />,
+              })
+            }
           >
             <Tooltip title="查看">
               <SearchOutlined />

+ 44 - 31
src/pages/device/Instance/Detail/MetadataMap/EditableTable/index.tsx

@@ -1,7 +1,7 @@
 import React, { useContext, useEffect, useState } from 'react';
 import { Form, Input, message, Pagination, Select, Table } from 'antd';
 import { service } from '@/pages/device/Instance';
-import { QuestionCircleOutlined } from '@ant-design/icons';
+import _ from 'lodash';
 
 const EditableContext: any = React.createContext(null);
 
@@ -42,7 +42,11 @@ const EditableCell = ({
   const save = async () => {
     try {
       const values = await form.validateFields();
-      handleSave({ ...record, ...values });
+      if (values) {
+        handleSave({ ...record, ...values });
+      } else {
+        console.log(values);
+      }
     } catch (errInfo) {
       console.log('Save failed:', errInfo);
     }
@@ -62,6 +66,7 @@ const EditableCell = ({
         <Select
           onChange={save}
           showSearch
+          allowClear
           optionFilterProp="children"
           filterOption={(input: string, option: any) =>
             (option?.children || '').toLowerCase()?.indexOf(input.toLowerCase()) >= 0
@@ -111,6 +116,7 @@ const EditableTable = (props: Props) => {
     total: properties.length,
   });
   const [protocolMetadata, setProtocolMetadata] = useState<any[]>([]);
+  const [pmList, setPmList] = useState<any[]>([]);
 
   const components = {
     body: {
@@ -132,12 +138,19 @@ const EditableTable = (props: Props) => {
       data.map((i: any) => {
         obj[i?.originalId] = i?.metadataId || '';
       });
-      const list = properties.map((item) => {
-        return {
-          ...item,
-          metadataId: obj[item.id] || '',
-        };
-      });
+      if (protocolMetadata.length > 0) {
+        setPmList(protocolMetadata.filter((i) => !_.map(data, 'metadataId').includes(i.id)));
+      } else {
+        setPmList([]);
+      }
+      const list = (JSON.parse(props?.data?.metadata || '{}')?.properties || []).map(
+        (item: any) => {
+          return {
+            ...item,
+            metadataId: obj[item.id] || '',
+          };
+        },
+      );
       setProperties([...list]);
       setDataSource({
         data: list.slice(
@@ -152,18 +165,20 @@ const EditableTable = (props: Props) => {
   };
 
   useEffect(() => {
-    service
-      .queryProtocolMetadata(
-        props.type === 'device' ? props.data?.protocol : props.data?.messageProtocol,
-        props.type === 'device' ? props.data?.transport : props.data?.transportProtocol,
-      )
-      .then((resp) => {
-        if (resp.status === 200) {
-          setProtocolMetadata(JSON.parse(resp.result || '{}')?.properties || []);
-          initData();
-        }
-      });
-  }, []);
+    if (props.data && Object.keys(props.data).length > 0) {
+      service
+        .queryProtocolMetadata(
+          props.type === 'device' ? props.data?.protocol : props.data?.messageProtocol,
+          props.type === 'device' ? props.data?.transport : props.data?.transportProtocol,
+        )
+        .then((resp) => {
+          if (resp.status === 200) {
+            setProtocolMetadata(JSON.parse(resp.result || '{}')?.properties || []);
+            initData();
+          }
+        });
+    }
+  }, [props.data]);
 
   const handleSave = async (row: any) => {
     const newData = [...dataSource.data];
@@ -231,7 +246,7 @@ const EditableTable = (props: Props) => {
         editable: col.editable,
         dataIndex: col.dataIndex,
         title: col.title,
-        list: protocolMetadata,
+        list: pmList,
         handleSave: handleSave,
       }),
     };
@@ -253,16 +268,14 @@ const EditableTable = (props: Props) => {
             });
           }}
         />
-        <div>
-          <div style={{ color: 'rgba(0, 0, 0, .65)' }}>
-            <QuestionCircleOutlined style={{ margin: 5 }} />
-            该设备已脱离产品物模型映射,修改产品物模型映射对该设备物模型映射无影响
-          </div>
-          <div style={{ color: 'rgba(0, 0, 0, .65)' }}>
-            <QuestionCircleOutlined style={{ margin: 5 }} />
-            设备会默认继承产品的物模型映射,修改设备物模型映射后将脱离产品物模型映射
-          </div>
-        </div>
+        {/* <div style={{ color: 'rgba(0, 0, 0, .65)' }}>
+                    <QuestionCircleOutlined style={{ margin: 5 }} />
+                    {
+                        props?.data?.independentMetadata ?
+                            '该设备已脱离产品物模型映射,修改产品物模型映射对该设备物模型映射无影响' :
+                            '设备会默认继承产品的物模型映射,修改设备物模型映射后将脱离产品物模型映射'
+                    }
+                </div> */}
       </div>
       <Table
         components={components}

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

@@ -23,6 +23,7 @@ const Tags = () => {
       <Descriptions
         style={{ marginBottom: 20 }}
         bordered
+        column={3}
         size="small"
         title={
           <span>
@@ -43,7 +44,7 @@ const Tags = () => {
         }
       >
         {(tags || [])?.map((item: any) => (
-          <Descriptions.Item label={`${item.name}(${item.key})`} key={item.key}>
+          <Descriptions.Item span={1} label={`${item.name}(${item.key})`} key={item.key}>
             {item.value || '--'}
           </Descriptions.Item>
         ))}

+ 2 - 2
src/pages/device/Instance/service.ts

@@ -195,7 +195,7 @@ class Service extends BaseService<DeviceInstance> {
     });
   // 执行功能
   public executeFunctions = (deviceId: string, functionId: string, data: any) =>
-    request(`/${SystemConst.API_BASE}device/invoked/${deviceId}/function/${functionId}`, {
+    request(`/${SystemConst.API_BASE}/device/invoked/${deviceId}/function/${functionId}`, {
       method: 'POST',
       data,
     });
@@ -207,7 +207,7 @@ class Service extends BaseService<DeviceInstance> {
     });
   // 设置属性
   public settingProperties = (deviceId: string, data: any) =>
-    request(`/${SystemConst.API_BASE}/device/setting/${deviceId}/property`, {
+    request(`/${SystemConst.API_BASE}//device-instance/${deviceId}/property`, {
       method: 'POST',
       data,
     });

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

@@ -41,7 +41,7 @@ const AccessConfig = (props: Props) => {
     service
       .queryList({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
       .then((resp) => {
-        setDataSource(resp.result);
+        setDataSource(resp?.result);
       });
   };
 
@@ -140,7 +140,7 @@ const AccessConfig = (props: Props) => {
         </div>
       </div>
       <Row gutter={[16, 16]}>
-        {dataSource.data.map((item: any) => (
+        {(dataSource?.data || []).map((item: any) => (
           <Col
             key={item.name}
             span={12}

+ 27 - 21
src/pages/link/AccessConfig/index.tsx

@@ -2,7 +2,7 @@ import SearchComponent from '@/components/SearchComponent';
 import { getButtonPermission, getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 import { PageContainer } from '@ant-design/pro-layout';
 import type { ProColumns } from '@jetlinks/pro-table';
-import { Button, Card, Col, Empty, message, Pagination, Popconfirm, Row } from 'antd';
+import { Button, Card, Col, Empty, message, Pagination, Popconfirm, Row, Tooltip } from 'antd';
 import { useEffect, useState } from 'react';
 import { useHistory } from 'umi';
 import Service from './service';
@@ -13,7 +13,7 @@ export const service = new Service('gateway/device');
 
 const AccessConfig = () => {
   const history = useHistory();
-  const [param, setParam] = useState<any>({ pageSize: 10 });
+  const [param, setParam] = useState<any>({ pageSize: 10, terms: [] });
 
   const columns: ProColumns<any>[] = [
     {
@@ -148,28 +148,34 @@ const AccessConfig = () => {
                         )}
                       </Popconfirm>
                     </Button>,
-                    <Button
+                    <Tooltip
                       key="delete"
-                      type="link"
-                      disabled={getButtonPermission('link/AccessConfig', ['delete'])}
+                      title={
+                        getButtonPermission('link/AccessConfig', ['delete']) ? '没有权限' : '删除'
+                      }
                     >
-                      <Popconfirm
-                        title={'确认删除?'}
-                        onConfirm={() => {
-                          service.remove(item.id).then((resp: any) => {
-                            if (resp.status === 200) {
-                              message.success('操作成功!');
-                              handleSearch(param);
-                            } else {
-                              message.error(resp.message);
-                            }
-                          });
-                        }}
+                      <Button
+                        type="link"
+                        disabled={getButtonPermission('link/AccessConfig', ['delete'])}
                       >
-                        <DeleteOutlined />
-                        删除
-                      </Popconfirm>
-                    </Button>,
+                        <Popconfirm
+                          title={'确认删除?'}
+                          onConfirm={() => {
+                            service.remove(item.id).then((resp: any) => {
+                              if (resp.status === 200) {
+                                message.success('操作成功!');
+                                handleSearch(param);
+                              } else {
+                                message.error(resp?.message || '操作失败');
+                              }
+                            });
+                          }}
+                        >
+                          <DeleteOutlined />
+                          删除
+                        </Popconfirm>
+                      </Button>
+                    </Tooltip>,
                   ]}
                 />
               </Col>

+ 21 - 10
src/pages/media/Cascade/Channel/index.tsx

@@ -19,6 +19,7 @@ const Channel = () => {
   const [selectedRowKey, setSelectedRowKey] = useState<string[]>([]);
   const id = location?.query?.id || '';
   const [data, setData] = useState<string>('');
+  const [popVisible, setPopvisible] = useState<string>('');
 
   const unbind = async (list: string[]) => {
     const resp = await service.unbindChannel(id, list);
@@ -43,9 +44,11 @@ const Channel = () => {
           style={{ marginTop: 10, width: '100%' }}
           onClick={async () => {
             if (!!data) {
-              const resp: any = service.editBindInfo(record.id, { gbChannelId: data });
+              const resp: any = await service.editBindInfo(record.id, { gbChannelId: data });
               if (resp.status === 200) {
+                message.success('操作成功');
                 actionRef.current?.reload();
+                setPopvisible('');
               }
             } else {
               message.error('请输入国标ID');
@@ -68,17 +71,23 @@ const Channel = () => {
       title: '通道名称',
     },
     {
-      dataIndex: 'channelId',
+      dataIndex: 'gbChannelId',
       title: '国标ID',
       tooltip: '国标级联有18位、20位两种格式。在当前页面修改不会修改视频设备-通道页面中的国标ID',
       render: (text: any, record: any) => (
         <span>
           {text}
-          <Popover trigger="click" content={content(record)} title="编辑通道ID">
+          <Popover
+            visible={popVisible === record.id}
+            trigger="click"
+            content={content(record)}
+            title="编辑国标ID"
+          >
             <a
               style={{ marginLeft: 10 }}
               onClick={() => {
                 setData('');
+                setPopvisible(record.id);
               }}
             >
               <EditOutlined />
@@ -119,7 +128,7 @@ const Channel = () => {
           key={'unbinds'}
           title="确认解绑"
           onConfirm={() => {
-            unbind([record.id]);
+            unbind([record.channelId]);
           }}
         >
           <a>
@@ -136,7 +145,7 @@ const Channel = () => {
     <PageContainer>
       <SearchComponent<any>
         field={columns}
-        target="unbind-channel"
+        target="bind-channel"
         onSearch={(params) => {
           actionRef.current?.reload();
           setParam({
@@ -157,7 +166,7 @@ const Channel = () => {
             sorts: [{ name: 'createTime', order: 'desc' }],
           })
         }
-        rowKey="id"
+        rowKey="channelId"
         rowSelection={{
           selectedRowKeys: selectedRowKey,
           onChange: (selectedRowKeys) => {
@@ -195,18 +204,20 @@ const Channel = () => {
           >
             绑定通道
           </Button>,
-          <Button
-            onClick={() => {
+          <Popconfirm
+            title={'确认解绑'}
+            onConfirm={() => {
               if (selectedRowKey.length > 0) {
                 unbind(selectedRowKey);
+                setSelectedRowKey([]);
               } else {
                 message.error('请先选择需要解绑的通道列表');
               }
             }}
             key="unbind"
           >
-            批量解绑
-          </Button>,
+            <Button>批量解绑</Button>
+          </Popconfirm>,
         ]}
       />
       {visible && (

+ 26 - 12
src/pages/media/Cascade/index.tsx

@@ -68,21 +68,29 @@ const Cascade = () => {
         选择通道
       </Tooltip>
     </Button>,
-    <Button type={'link'} key={'share'} disabled={record.status.value === 'disabled'}>
-      <Popconfirm
+    <Tooltip
+      key={'share'}
+      title={record.status.value === 'disabled' ? '禁用状态下不可推送' : '推送'}
+    >
+      <Button
+        type={'link'}
         key={'share'}
-        title="确认推送!"
-        onConfirm={() => {
-          setCurrent(record);
-          setVisible(true);
-        }}
+        disabled={
+          getButtonPermission('media/Cascade', ['push']) || record.status.value === 'disabled'
+        }
       >
-        <Tooltip title={record.status.value === 'disabled' ? '禁用状态下不可推送' : '推送'}>
+        <Popconfirm
+          title="确认推送!"
+          onConfirm={() => {
+            setCurrent(record);
+            setVisible(true);
+          }}
+        >
           <ShareAltOutlined />
           推送
-        </Tooltip>
-      </Popconfirm>
-    </Button>,
+        </Popconfirm>
+      </Button>
+    </Tooltip>,
     <Button
       type={'link'}
       key={'operate'}
@@ -262,7 +270,13 @@ const Cascade = () => {
           title={record.status.value === 'disabled' ? '禁用状态下不可推送' : '推送'}
           key={'share'}
         >
-          <Button type="link" style={{ padding: 0 }} disabled={record.status.value === 'disabled'}>
+          <Button
+            type="link"
+            style={{ padding: 0 }}
+            disabled={
+              getButtonPermission('media/Cascade', ['push']) || record.status.value === 'disabled'
+            }
+          >
             <Popconfirm
               onConfirm={() => {
                 setVisible(true);

+ 73 - 64
src/pages/rule-engine/Instance/index.tsx

@@ -117,40 +117,47 @@ const Instance = () => {
         </Tooltip>
       </Popconfirm>
     </Button>,
-    <Button
-      type={'link'}
+    <Tooltip
       key={'delete'}
-      style={{ padding: 0 }}
-      disabled={getButtonPermission('rule-engine/Instance', ['delete'])}
+      title={
+        record.state.value !== 'disable'
+          ? '已启用不能删除'
+          : intl.formatMessage({
+              id: 'pages.data.option.remove',
+              defaultMessage: '删除',
+            })
+      }
     >
-      <Popconfirm
-        title={record.state.value === 'disable' ? '确认删除' : '未停止不能删除'}
-        key={'delete'}
-        onConfirm={async () => {
-          if (record.state.value === 'disable') {
-            await service.remove(record.id);
-            message.success(
-              intl.formatMessage({
-                id: 'pages.data.option.success',
-                defaultMessage: '操作成功!',
-              }),
-            );
-            actionRef.current?.reload();
-          } else {
-            message.error('未停止不能删除');
-          }
-        }}
+      <Button
+        type={'link'}
+        style={{ padding: 0 }}
+        disabled={
+          getButtonPermission('rule-engine/Instance', ['delete']) ||
+          record.state.value !== 'disable'
+        }
       >
-        <Tooltip
-          title={intl.formatMessage({
-            id: 'pages.data.option.remove',
-            defaultMessage: '删除',
-          })}
+        <Popconfirm
+          title={record.state.value === 'disable' ? '确认删除' : '未停止不能删除'}
+          key={'delete'}
+          onConfirm={async () => {
+            if (record.state.value === 'disable') {
+              await service.remove(record.id);
+              message.success(
+                intl.formatMessage({
+                  id: 'pages.data.option.success',
+                  defaultMessage: '操作成功!',
+                }),
+              );
+              actionRef.current?.reload();
+            } else {
+              message.error('未停止不能删除');
+            }
+          }}
         >
           <DeleteOutlined />
-        </Tooltip>
-      </Popconfirm>
-    </Button>,
+        </Popconfirm>
+      </Button>
+    </Tooltip>,
   ];
 
   const columns: ProColumns<InstanceItem>[] = [
@@ -223,7 +230,6 @@ const Instance = () => {
         <Button
           type="link"
           style={{ padding: 0 }}
-          disabled={getButtonPermission('rule-engine/Instance', ['view'])}
           key={'view'}
           onClick={() => {
             window.open(`/${SystemConst.API_BASE}/rule-editor/index.html#flow/${record.id}`);
@@ -279,40 +285,47 @@ const Instance = () => {
             </Tooltip>
           </Popconfirm>
         </Button>,
-        <Button
-          disabled={getButtonPermission('rule-engine/Instance', ['delete'])}
-          type={'link'}
+        <Tooltip
           key={'delete'}
-          style={{ padding: 0 }}
+          title={
+            record.state.value !== 'disable'
+              ? '已启用不能删除'
+              : intl.formatMessage({
+                  id: 'pages.data.option.remove',
+                  defaultMessage: '删除',
+                })
+          }
         >
-          <Popconfirm
-            title={record.state.value === 'disable' ? '确认删除' : '未禁用不能删除'}
-            key={'delete'}
-            onConfirm={async () => {
-              if (record.state.value === 'disable') {
-                await service.remove(record.id);
-                message.success(
-                  intl.formatMessage({
-                    id: 'pages.data.option.success',
-                    defaultMessage: '操作成功!',
-                  }),
-                );
-                actionRef.current?.reload();
-              } else {
-                message.error('未禁用不能删除');
-              }
-            }}
+          <Button
+            disabled={
+              getButtonPermission('rule-engine/Instance', ['delete']) ||
+              record.state.value !== 'disable'
+            }
+            type={'link'}
+            style={{ padding: 0 }}
           >
-            <Tooltip
-              title={intl.formatMessage({
-                id: 'pages.data.option.remove',
-                defaultMessage: '删除',
-              })}
+            <Popconfirm
+              title={record.state.value === 'disable' ? '确认删除' : '未禁用不能删除'}
+              key={'delete'}
+              onConfirm={async () => {
+                if (record.state.value === 'disable') {
+                  await service.remove(record.id);
+                  message.success(
+                    intl.formatMessage({
+                      id: 'pages.data.option.success',
+                      defaultMessage: '操作成功!',
+                    }),
+                  );
+                  actionRef.current?.reload();
+                } else {
+                  message.error('未禁用不能删除');
+                }
+              }}
             >
               <DeleteOutlined />
-            </Tooltip>
-          </Popconfirm>
-        </Button>,
+            </Popconfirm>
+          </Button>
+        </Tooltip>,
       ],
     },
   ];
@@ -373,11 +386,7 @@ const Instance = () => {
               <div
                 style={{ padding: 8, fontSize: 24 }}
                 onClick={() => {
-                  if (!getButtonPermission('rule-engine/Instance', ['view'])) {
-                    window.open(
-                      `/${SystemConst.API_BASE}/rule-editor/index.html#flow/${record.id}`,
-                    );
-                  }
+                  window.open(`/${SystemConst.API_BASE}/rule-editor/index.html#flow/${record.id}`);
                 }}
               >
                 <EyeOutlined />