Bläddra i källkod

fix: 修改运行状态按钮权限

100011797 3 år sedan
förälder
incheckning
9903fbfd69

+ 2 - 1
src/app.tsx

@@ -187,7 +187,8 @@ export const request: RequestConfig = {
       response.status === 400 ||
       response.status === 400 ||
       response.status === 500 ||
       response.status === 500 ||
       response.status === 404 ||
       response.status === 404 ||
-      response.status === 403
+      response.status === 403 ||
+      response.status === 504
     ) {
     ) {
       // 添加clone() 避免后续其它地方用response.text()时报错
       // 添加clone() 避免后续其它地方用response.text()时报错
       response
       response

+ 3 - 3
src/components/ProTableCard/CardItems/DataCollect/channel.tsx

@@ -30,13 +30,13 @@ export default (props: ChannelCardProps) => {
       showMask={false}
       showMask={false}
       statusNames={{
       statusNames={{
         running: StatusColorEnum.success,
         running: StatusColorEnum.success,
-        disabled: StatusColorEnum.processing,
+        disabled: StatusColorEnum.error,
         partialError: StatusColorEnum.warning,
         partialError: StatusColorEnum.warning,
-        failed: StatusColorEnum.error,
+        failed: StatusColorEnum.processing,
         stopped: StatusColorEnum.default,
         stopped: StatusColorEnum.default,
       }}
       }}
     >
     >
-      <div className={'pro-table-card-item'}>
+      <div className={'pro-table-card-item'} onClick={props?.onClick}>
         <div className={'card-item-avatar'}>
         <div className={'card-item-avatar'}>
           <img
           <img
             width={88}
             width={88}

+ 4 - 1
src/components/ProTableCard/CardItems/cascade.tsx

@@ -37,7 +37,10 @@ export default (props: CascadeCardProps) => {
           </div>
           </div>
           <div>通道数量: {props?.count || 0}</div>
           <div>通道数量: {props?.count || 0}</div>
           <div style={{ display: 'flex', width: '100%' }}>
           <div style={{ display: 'flex', width: '100%' }}>
-            <Badge status={props.onlineStatus?.value === 'offline' ? 'error' : 'success'} />
+            <Badge
+              style={{ marginRight: 5 }}
+              status={props.onlineStatus?.value === 'offline' ? 'error' : 'success'}
+            />
             {/*<div*/}
             {/*<div*/}
             {/*  style={{*/}
             {/*  style={{*/}
             {/*    width: '90%',*/}
             {/*    width: '90%',*/}

+ 8 - 0
src/components/ProTableCard/index.less

@@ -270,6 +270,14 @@
           background-color: rgba(#e50012, 0.1);
           background-color: rgba(#e50012, 0.1);
         }
         }
 
 
+        &.default {
+          background-color: rgba(229, 229, 229);
+        }
+
+        &.processing {
+          background-color: rgba(36, 178, 118, 0.1);
+        }
+
         .card-state-content {
         .card-state-content {
           transform: skewX(-45deg);
           transform: skewX(-45deg);
         }
         }

+ 8 - 0
src/pages/DataCollect/Channel/index.tsx

@@ -13,6 +13,8 @@ import ChannelCard from '@/components/ProTableCard/CardItems/DataCollect/channel
 import { DeleteOutlined, EditOutlined, PlayCircleOutlined, StopOutlined } from '@ant-design/icons';
 import { DeleteOutlined, EditOutlined, PlayCircleOutlined, StopOutlined } from '@ant-design/icons';
 import { onlyMessage } from '@/utils/util';
 import { onlyMessage } from '@/utils/util';
 import Save from '@/pages/DataCollect/Channel/Save';
 import Save from '@/pages/DataCollect/Channel/Save';
+import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
+import useHistory from '@/hooks/route/useHistory';
 
 
 const ChannelModel = model<{
 const ChannelModel = model<{
   visible: boolean;
   visible: boolean;
@@ -36,6 +38,8 @@ export default observer(() => {
     pageIndex: 0,
     pageIndex: 0,
     total: 0,
     total: 0,
   });
   });
+  const history = useHistory();
+
   const columns: ProColumns<ChannelItem>[] = [
   const columns: ProColumns<ChannelItem>[] = [
     {
     {
       title: '通道名称',
       title: '通道名称',
@@ -280,6 +284,10 @@ export default observer(() => {
                         <DeleteOutlined />
                         <DeleteOutlined />
                       </PermissionButton>,
                       </PermissionButton>,
                     ]}
                     ]}
+                    onClick={() => {
+                      const url = getMenuPathByCode(MENUS_CODE['DataCollect/Collector']);
+                      history.push(url, { channelId: record.id });
+                    }}
                   />
                   />
                 </Col>
                 </Col>
               ))}
               ))}

+ 6 - 8
src/pages/DataCollect/Collector/components/Device/Save/index.tsx

@@ -55,14 +55,12 @@ export default (props: Props) => {
             if (value) {
             if (value) {
               const dt = channelListRef.current.find((item) => item.id === value);
               const dt = channelListRef.current.find((item) => item.id === value);
               channelRef.current = dt;
               channelRef.current = dt;
-              if (dt?.provider && dt?.provider === 'MODBUS_TCP') {
-                f.setFieldState('configuration.unitId', (state) => {
-                  state.visible = true;
-                });
-                f.setFieldState('configuration.endian', (state) => {
-                  state.visible = true;
-                });
-              }
+              f.setFieldState('configuration.unitId', (state) => {
+                state.visible = dt?.provider && dt?.provider === 'MODBUS_TCP';
+              });
+              f.setFieldState('configuration.endian', (state) => {
+                state.visible = dt?.provider && dt?.provider === 'MODBUS_TCP';
+              });
             }
             }
           });
           });
           onFieldReact('circuitBreaker.type', async (field, f) => {
           onFieldReact('circuitBreaker.type', async (field, f) => {

+ 17 - 11
src/pages/DataCollect/Collector/components/Point/index.tsx

@@ -102,7 +102,7 @@ const PointCard = observer((props: PointCardProps) => {
         setPropertyValue({ ...propertyValue });
         setPropertyValue({ ...propertyValue });
       });
       });
   };
   };
-  const handleSearch = (params: any) => {
+  const handleSearch = async (params: any) => {
     if (subRef.current) {
     if (subRef.current) {
       subRef.current?.unsubscribe();
       subRef.current?.unsubscribe();
     }
     }
@@ -111,8 +111,8 @@ const PointCard = observer((props: PointCardProps) => {
     PointModel.list = [];
     PointModel.list = [];
     setLoading(true);
     setLoading(true);
     setParam(params);
     setParam(params);
-    service
-      .queryPoint({
+    if (props.data?.id) {
+      const resp = await service.queryPoint({
         ...params,
         ...params,
         terms: [
         terms: [
           ...params?.terms,
           ...params?.terms,
@@ -123,14 +123,20 @@ const PointCard = observer((props: PointCardProps) => {
           },
           },
         ],
         ],
         sorts: [{ name: 'id', order: 'desc' }],
         sorts: [{ name: 'id', order: 'desc' }],
-      })
-      .then((resp) => {
-        if (resp.status === 200) {
-          setDataSource(resp.result);
-          subscribeProperty((resp.result?.data || []).map((item: any) => item.id));
-        }
-        setLoading(false);
       });
       });
+      if (resp.status === 200) {
+        setDataSource(resp.result);
+        subscribeProperty((resp.result?.data || []).map((item: any) => item.id));
+      }
+    } else {
+      setDataSource({
+        data: [],
+        pageSize: 12,
+        pageIndex: 0,
+        total: 0,
+      });
+    }
+    setLoading(false);
   };
   };
 
 
   useEffect(() => {
   useEffect(() => {
@@ -235,7 +241,7 @@ const PointCard = observer((props: PointCardProps) => {
       >
       >
         <div>
         <div>
           <div style={{ height: '100%', paddingBottom: 48 }}>
           <div style={{ height: '100%', paddingBottom: 48 }}>
-            {props.data?.id !== '*' && (
+            {props.data?.id !== '*' && props.data?.id && (
               <div style={{ width: '100%', display: 'flex', justifyContent: 'flex-start' }}>
               <div style={{ width: '100%', display: 'flex', justifyContent: 'flex-start' }}>
                 <PermissionButton
                 <PermissionButton
                   isPermission={permission.add}
                   isPermission={permission.add}

+ 53 - 28
src/pages/DataCollect/Collector/components/Tree/index.tsx

@@ -24,15 +24,20 @@ const TreeModel = model<{
   param: any;
   param: any;
   visible: boolean;
   visible: boolean;
   current: any;
   current: any;
+  search: string;
 }>({
 }>({
   selectedKeys: ['*'],
   selectedKeys: ['*'],
   dataSource: [],
   dataSource: [],
   loading: true,
   loading: true,
-  param: {},
+  param: {
+    terms: [],
+  },
   visible: false,
   visible: false,
   current: {},
   current: {},
+  search: '',
 });
 });
 interface Props {
 interface Props {
+  channelId?: string;
   change: (data?: any) => void;
   change: (data?: any) => void;
 }
 }
 
 
@@ -41,33 +46,50 @@ export default observer((props: Props) => {
   const { permission } = PermissionButton.usePermission('DataCollect/Collector');
   const { permission } = PermissionButton.usePermission('DataCollect/Collector');
   const intl = useIntl();
   const intl = useIntl();
 
 
-  const handleSearch = (params: any) => {
+  const handleSearch = async (params: any) => {
     TreeModel.loading = true;
     TreeModel.loading = true;
     TreeModel.param = params;
     TreeModel.param = params;
-    service
-      .queryCollector({ ...params, paging: false, sorts: [{ name: 'createTime', order: 'desc' }] })
-      .then((resp) => {
-        if (resp.status === 200) {
-          if (params.terms) {
-            TreeModel.dataSource = resp.result;
-          } else {
-            TreeModel.dataSource = [
-              {
-                id: '*',
-                name: '全部',
-                children: resp.result,
-              },
-            ];
-          }
-          props.change(TreeModel.dataSource[0]);
-        }
-        TreeModel.loading = false;
-      });
+    const resp = await service.queryCollector({
+      ...params,
+      paging: false,
+      sorts: [{ name: 'createTime', order: 'desc' }],
+    });
+    if (resp.status === 200) {
+      if (TreeModel?.search || props?.channelId) {
+        TreeModel.dataSource = resp.result;
+      } else {
+        TreeModel.dataSource = [
+          {
+            id: '*',
+            name: '全部',
+            children: resp.result,
+          },
+        ];
+      }
+      TreeModel.selectedKeys = [TreeModel.dataSource?.[0]?.id] || [];
+      props.change(TreeModel.dataSource?.[0]);
+    }
+    TreeModel.loading = false;
   };
   };
 
 
   useEffect(() => {
   useEffect(() => {
-    handleSearch(TreeModel.param);
-  }, [TreeModel.param]);
+    if (props.channelId) {
+      TreeModel.param = {
+        terms: [
+          {
+            column: 'channelId',
+            value: props?.channelId,
+          },
+        ],
+      };
+      handleSearch(TreeModel.param);
+    } else {
+      TreeModel.param = {
+        terms: [],
+      };
+      handleSearch(TreeModel.param);
+    }
+  }, [props.channelId]);
 
 
   const getState = (record: any) => {
   const getState = (record: any) => {
     if (record) {
     if (record) {
@@ -99,13 +121,15 @@ export default observer((props: Props) => {
           placeholder="请输入名称"
           placeholder="请输入名称"
           allowClear
           allowClear
           onSearch={(val) => {
           onSearch={(val) => {
+            TreeModel.search = val;
             if (val) {
             if (val) {
               TreeModel.param = {
               TreeModel.param = {
                 terms: [{ column: 'name', value: `%${val}%`, termType: 'like' }],
                 terms: [{ column: 'name', value: `%${val}%`, termType: 'like' }],
               };
               };
             } else {
             } else {
-              TreeModel.param = {};
+              TreeModel.param = { terms: [] };
             }
             }
+            handleSearch(TreeModel.param);
           }}
           }}
           style={{ width: '100%' }}
           style={{ width: '100%' }}
         />
         />
@@ -133,6 +157,7 @@ export default observer((props: Props) => {
             height={500}
             height={500}
             selectedKeys={TreeModel.selectedKeys}
             selectedKeys={TreeModel.selectedKeys}
             defaultExpandAll
             defaultExpandAll
+            autoExpandParent
             switcherIcon={<DownOutlined />}
             switcherIcon={<DownOutlined />}
             fieldNames={{
             fieldNames={{
               title: 'name',
               title: 'name',
@@ -196,7 +221,7 @@ export default observer((props: Props) => {
                                   runningState: 'running',
                                   runningState: 'running',
                                 });
                                 });
                           if (resp.status === 200) {
                           if (resp.status === 200) {
-                            TreeModel.param = {};
+                            TreeModel.param = { terms: [] };
                             handleSearch(TreeModel.param);
                             handleSearch(TreeModel.param);
                             onlyMessage('操作成功');
                             onlyMessage('操作成功');
                           } else {
                           } else {
@@ -218,7 +243,7 @@ export default observer((props: Props) => {
                         onConfirm={async () => {
                         onConfirm={async () => {
                           const resp = await service.removeCollector(i.id);
                           const resp = await service.removeCollector(i.id);
                           if (resp.status === 200) {
                           if (resp.status === 200) {
-                            TreeModel.param = {};
+                            TreeModel.param = { terms: [] };
                             handleSearch(TreeModel.param);
                             handleSearch(TreeModel.param);
                             onlyMessage('操作成功');
                             onlyMessage('操作成功');
                           }
                           }
@@ -242,7 +267,7 @@ export default observer((props: Props) => {
               </div>
               </div>
             )}
             )}
             treeData={TreeModel.dataSource}
             treeData={TreeModel.dataSource}
-          ></Tree>
+          />
         ) : (
         ) : (
           <Empty />
           <Empty />
         )}
         )}
@@ -255,7 +280,7 @@ export default observer((props: Props) => {
           }}
           }}
           reload={() => {
           reload={() => {
             TreeModel.visible = false;
             TreeModel.visible = false;
-            TreeModel.param = {};
+            TreeModel.param = { terms: [] };
             handleSearch(TreeModel.param);
             handleSearch(TreeModel.param);
           }}
           }}
         />
         />

+ 15 - 1
src/pages/DataCollect/Collector/index.tsx

@@ -5,28 +5,42 @@ import CollectorTree from './components/Tree';
 import { observer } from '@formily/reactive-react';
 import { observer } from '@formily/reactive-react';
 import { model } from '@formily/reactive';
 import { model } from '@formily/reactive';
 import Point from './components/Point';
 import Point from './components/Point';
+import { useEffect } from 'react';
+import useLocations from '@/hooks/route/useLocation';
 
 
 export const DataCollectModel = model<{
 export const DataCollectModel = model<{
   provider: 'OPC_UA' | 'MODBUS_TCP';
   provider: 'OPC_UA' | 'MODBUS_TCP';
   data: any;
   data: any;
   reload: boolean;
   reload: boolean;
   refresh: boolean;
   refresh: boolean;
+  channelId: string;
 }>({
 }>({
   provider: 'MODBUS_TCP',
   provider: 'MODBUS_TCP',
   data: {},
   data: {},
   reload: false,
   reload: false,
   refresh: false,
   refresh: false,
+  channelId: '',
 });
 });
 
 
 export default observer(() => {
 export default observer(() => {
+  const location = useLocations();
+
+  useEffect(() => {
+    if (location.state?.channelId) {
+      DataCollectModel.channelId = location.state.channelId;
+    } else {
+      DataCollectModel.channelId = '';
+    }
+  }, [location.state]);
   return (
   return (
     <PageContainer>
     <PageContainer>
       <Card bordered={false} bodyStyle={{ paddingTop: 0 }}>
       <Card bordered={false} bodyStyle={{ paddingTop: 0 }}>
         <div className={styles.container}>
         <div className={styles.container}>
           <div className={styles.left}>
           <div className={styles.left}>
             <CollectorTree
             <CollectorTree
+              channelId={DataCollectModel.channelId}
               change={(data) => {
               change={(data) => {
-                DataCollectModel.provider = data.provider;
+                DataCollectModel.provider = data?.provider;
                 DataCollectModel.data = data || {};
                 DataCollectModel.data = data || {};
               }}
               }}
             />
             />

+ 111 - 29
src/pages/device/Instance/Detail/ChildDevice/index.tsx

@@ -1,7 +1,7 @@
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
 import type { LogItem } from '@/pages/device/Instance/Detail/Log/typings';
 import type { LogItem } from '@/pages/device/Instance/Detail/Log/typings';
-import { Badge, Button, Card, Popconfirm, Tooltip } from 'antd';
+import { Badge, Card, Tooltip } from 'antd';
 import { DisconnectOutlined, EditOutlined, SearchOutlined } from '@ant-design/icons';
 import { DisconnectOutlined, EditOutlined, SearchOutlined } from '@ant-design/icons';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { InstanceModel, service } from '@/pages/device/Instance';
 import { InstanceModel, service } from '@/pages/device/Instance';
@@ -14,6 +14,7 @@ import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { useDomFullHeight } from '@/hooks';
 import { useDomFullHeight } from '@/hooks';
 import { onlyMessage } from '@/utils/util';
 import { onlyMessage } from '@/utils/util';
 import SaveChild from './SaveChild';
 import SaveChild from './SaveChild';
+import PermissionButton from '../../../../../components/PermissionButton';
 
 
 const statusMap = new Map();
 const statusMap = new Map();
 statusMap.set('online', 'success');
 statusMap.set('online', 'success');
@@ -32,6 +33,7 @@ const ChildDevice = (props: Props) => {
   const [bindKeys, setBindKeys] = useState<any[]>([]);
   const [bindKeys, setBindKeys] = useState<any[]>([]);
   const [childVisible, setChildVisible] = useState<boolean>(false);
   const [childVisible, setChildVisible] = useState<boolean>(false);
   const [current, setCurrent] = useState<any>({});
   const [current, setCurrent] = useState<any>({});
+  const devicePermission = PermissionButton.usePermission('device/Instance').permission;
 
 
   const { minHeight } = useDomFullHeight(`.device-detail-childDevice`);
   const { minHeight } = useDomFullHeight(`.device-detail-childDevice`);
 
 
@@ -149,30 +151,63 @@ const ChildDevice = (props: Props) => {
             <SearchOutlined />
             <SearchOutlined />
           </Tooltip>
           </Tooltip>
         </Link>,
         </Link>,
-        <a key="unbind">
-          <Popconfirm
-            onConfirm={() => {
+        // <a key="unbind">
+        //   <Popconfirm
+        //     onConfirm={() => {
+        //       unBindSingleDevice(record.id);
+        //     }}
+        //     title={'确认解绑吗?'}
+        //   >
+        //     <Tooltip title={'解绑'}>
+        //       <DisconnectOutlined />
+        //     </Tooltip>
+        //   </Popconfirm>
+        // </a>,
+        <PermissionButton
+          key="unbind"
+          type={'link'}
+          popConfirm={{
+            title: '确认解绑吗?',
+            onConfirm: async () => {
               unBindSingleDevice(record.id);
               unBindSingleDevice(record.id);
-            }}
-            title={'确认解绑吗?'}
-          >
-            <Tooltip title={'解绑'}>
-              <DisconnectOutlined />
-            </Tooltip>
-          </Popconfirm>
-        </a>,
+            },
+          }}
+          tooltip={{
+            title: devicePermission.update ? '解绑' : '暂无权限,请联系管理员',
+          }}
+          style={{ padding: 0 }}
+          isPermission={devicePermission.update}
+        >
+          <DisconnectOutlined />
+        </PermissionButton>,
         <>
         <>
           {props.data.accessProvider === 'official-edge-gateway' && (
           {props.data.accessProvider === 'official-edge-gateway' && (
-            <a
+            // <a
+            //   onClick={() => {
+            //     setCurrent(record);
+            //     setChildVisible(true);
+            //   }}
+            // >
+            //   <Tooltip title={'编辑'} key={'edit'}>
+            //     <EditOutlined />
+            //   </Tooltip>
+            // </a>
+            <PermissionButton
+              key={'edit'}
+              type={'link'}
               onClick={() => {
               onClick={() => {
                 setCurrent(record);
                 setCurrent(record);
                 setChildVisible(true);
                 setChildVisible(true);
               }}
               }}
+              tooltip={{
+                placement: 'top',
+                title: devicePermission.update ? '编辑' : '暂无权限,请联系管理员',
+              }}
+              style={{ padding: 0 }}
+              isPermission={devicePermission.update}
             >
             >
-              <Tooltip title={'编辑'} key={'edit'}>
-                <EditOutlined />
-              </Tooltip>
-            </a>
+              <EditOutlined />
+            </PermissionButton>
           )}
           )}
         </>,
         </>,
       ],
       ],
@@ -227,32 +262,79 @@ const ChildDevice = (props: Props) => {
             toolBarRender={() => [
             toolBarRender={() => [
               <>
               <>
                 {props.data.accessProvider === 'official-edge-gateway' && (
                 {props.data.accessProvider === 'official-edge-gateway' && (
-                  <Button
+                  // <Button
+                  //   onClick={() => {
+                  //     // actionRef.current?.reset?.();
+                  //     setCurrent({});
+                  //     setChildVisible(true);
+                  //   }}
+                  //   key="save"
+                  //   type="primary"
+                  // >
+                  //   新增并绑定
+                  // </Button>
+                  <PermissionButton
+                    key={'edit'}
+                    type={'primary'}
                     onClick={() => {
                     onClick={() => {
-                      // actionRef.current?.reset?.();
                       setCurrent({});
                       setCurrent({});
                       setChildVisible(true);
                       setChildVisible(true);
                     }}
                     }}
-                    key="save"
-                    type="primary"
+                    tooltip={{
+                      placement: 'top',
+                      title: devicePermission.update ? '' : '暂无权限,请联系管理员',
+                    }}
+                    isPermission={devicePermission.update}
                   >
                   >
                     新增并绑定
                     新增并绑定
-                  </Button>
+                  </PermissionButton>
                 )}
                 )}
               </>,
               </>,
-              <Button
+              // <Button
+              //   onClick={() => {
+              //     setVisible(true);
+              //     actionRef.current?.reset?.();
+              //   }}
+              //   key="bind"
+              //   type="primary"
+              // >
+              //   绑定
+              // </Button>,
+              <PermissionButton
+                key={'bind'}
+                type={'primary'}
                 onClick={() => {
                 onClick={() => {
                   setVisible(true);
                   setVisible(true);
                   actionRef.current?.reset?.();
                   actionRef.current?.reset?.();
                 }}
                 }}
-                key="bind"
-                type="primary"
+                tooltip={{
+                  placement: 'top',
+                  title: devicePermission.update ? '' : '暂无权限,请联系管理员',
+                }}
+                isPermission={devicePermission.update}
               >
               >
                 绑定
                 绑定
-              </Button>,
-              <Popconfirm key="unbind" onConfirm={handleUnBind} title={'确认解绑吗?'}>
-                <Button>批量解绑</Button>
-              </Popconfirm>,
+              </PermissionButton>,
+              // <Popconfirm key="unbind" onConfirm={handleUnBind} title={'确认解绑吗?'}>
+              //   <Button>批量解绑</Button>
+              // </Popconfirm>,
+              <PermissionButton
+                key={'unbind'}
+                type={'primary'}
+                popConfirm={{
+                  title: '确认解绑吗?',
+                  onConfirm: async () => {
+                    handleUnBind();
+                  },
+                }}
+                tooltip={{
+                  placement: 'top',
+                  title: devicePermission.update ? '' : '暂无权限,请联系管理员',
+                }}
+                isPermission={devicePermission.update}
+              >
+                批量解绑
+              </PermissionButton>,
             ]}
             ]}
             pagination={{
             pagination={{
               pageSize: 10,
               pageSize: 10,

+ 1 - 1
src/pages/device/Instance/Detail/Running/Property/FileComponent/index.tsx

@@ -33,7 +33,7 @@ export const getType = (url: string) => {
   let t: string = '';
   let t: string = '';
   [...imgList, ...videoList, ...fileList].map((item) => {
   [...imgList, ...videoList, ...fileList].map((item) => {
     const str = item.slice(1, item.length);
     const str = item.slice(1, item.length);
-    if (url.indexOf(str) !== -1) {
+    if (url && String(url).indexOf(str) !== -1) {
       if (imgList.includes(item)) {
       if (imgList.includes(item)) {
         t = 'img';
         t = 'img';
       } else if (videoList.includes(item)) {
       } else if (videoList.includes(item)) {

+ 30 - 7
src/pages/device/Instance/Detail/Running/Property/PropertyCard.tsx

@@ -16,6 +16,7 @@ import Indicators from './Indicators';
 import './PropertyCard.less';
 import './PropertyCard.less';
 import FileComponent from './FileComponent';
 import FileComponent from './FileComponent';
 import { onlyMessage } from '@/utils/util';
 import { onlyMessage } from '@/utils/util';
+import PermissionButton from '../../../../../../components/PermissionButton';
 
 
 interface Props {
 interface Props {
   data: Partial<PropertyMetadata>;
   data: Partial<PropertyMetadata>;
@@ -26,6 +27,7 @@ const Property = (props: Props) => {
   const { data, value } = props;
   const { data, value } = props;
 
 
   const params = useParams<{ id: string }>();
   const params = useParams<{ id: string }>();
+  const devicePermission = PermissionButton.usePermission('device/Instance').permission;
 
 
   const [loading, setLoading] = useState<boolean>(false);
   const [loading, setLoading] = useState<boolean>(false);
   const refreshProperty = async () => {
   const refreshProperty = async () => {
@@ -53,13 +55,20 @@ const Property = (props: Props) => {
         </div>
         </div>
         <Space style={{ fontSize: 12 }}>
         <Space style={{ fontSize: 12 }}>
           {data.expands?.type?.includes('write') && (
           {data.expands?.type?.includes('write') && (
-            <Tooltip placement="top" title="设置属性至设备">
-              <EditOutlined
-                onClick={() => {
-                  setEditVisible(true);
-                }}
-              />
-            </Tooltip>
+            <PermissionButton
+              key={'edit'}
+              onClick={() => {
+                setEditVisible(true);
+              }}
+              tooltip={{
+                placement: 'top',
+                title: devicePermission.update ? '设置属性至设备' : '暂无权限,请联系管理员',
+              }}
+              style={{ padding: 0, border: 'none', backgroundColor: 'inherit' }}
+              isPermission={devicePermission.update}
+            >
+              <EditOutlined />
+            </PermissionButton>
           )}
           )}
           {(data.expands?.metrics || []).length > 0 &&
           {(data.expands?.metrics || []).length > 0 &&
             ['int', 'long', 'float', 'double', 'string', 'boolean', 'date'].includes(
             ['int', 'long', 'float', 'double', 'string', 'boolean', 'date'].includes(
@@ -72,6 +81,20 @@ const Property = (props: Props) => {
                   }}
                   }}
                 />
                 />
               </Tooltip>
               </Tooltip>
+              // <PermissionButton
+              //   key={'metrics'}
+              //   onClick={() => {
+              //     setIndicatorVisible(true);
+              //   }}
+              //   tooltip={{
+              //     placement: "top",
+              //     title: devicePermission.update ? "指标" : '暂无权限,请联系管理员'
+              //   }}
+              //   style={{ padding: 0, border: "none", backgroundColor: 'inherit' }}
+              //   isPermission={devicePermission.update}
+              // >
+              //   <ClockCircleOutlined  />
+              // </PermissionButton>
             )}
             )}
           {data.expands?.type?.includes('read') && (
           {data.expands?.type?.includes('read') && (
             <Tooltip placement="top" title="获取最新属性值">
             <Tooltip placement="top" title="获取最新属性值">

+ 34 - 10
src/pages/device/Instance/Detail/Running/Property/index.tsx

@@ -21,6 +21,7 @@ import PropertyTable from './PropertyTable';
 import { onlyMessage } from '@/utils/util';
 import { onlyMessage } from '@/utils/util';
 import Indicators from './Indicators';
 import Indicators from './Indicators';
 import { Empty } from '@/components';
 import { Empty } from '@/components';
+import PermissionButton from '../../../../../../components/PermissionButton';
 
 
 interface Props {
 interface Props {
   data: Partial<PropertyMetadata>[];
   data: Partial<PropertyMetadata>[];
@@ -51,6 +52,7 @@ const Property = (props: Props) => {
     pageSize: 8,
     pageSize: 8,
     currentPage: 0,
     currentPage: 0,
   });
   });
+  const devicePermission = PermissionButton.usePermission('device/Instance').permission;
   const [indicatorVisible, setIndicatorVisible] = useState<boolean>(false);
   const [indicatorVisible, setIndicatorVisible] = useState<boolean>(false);
   const [loading, setLoading] = useState<boolean>(true);
   const [loading, setLoading] = useState<boolean>(true);
 
 
@@ -94,16 +96,22 @@ const Property = (props: Props) => {
       render: (text: any, record: any) => (
       render: (text: any, record: any) => (
         <Space size="middle">
         <Space size="middle">
           {record.expands?.type?.includes('write') && (
           {record.expands?.type?.includes('write') && (
-            <Tooltip placement="top" title="设置属性至设备">
-              <a
-                onClick={() => {
-                  setVisible(true);
-                  setCurrentInfo(record);
-                }}
-              >
-                <EditOutlined />
-              </a>
-            </Tooltip>
+            <PermissionButton
+              type={'link'}
+              onClick={() => {
+                setVisible(true);
+                setCurrentInfo(record);
+              }}
+              tooltip={{
+                placement: 'top',
+                title: devicePermission.update ? '设置属性至设备' : '暂无权限,请联系管理员',
+              }}
+              style={{ padding: 0 }}
+              key={'edit'}
+              isPermission={devicePermission.update}
+            >
+              <EditOutlined />
+            </PermissionButton>
           )}
           )}
           {(record.expands?.metrics || []).length > 0 &&
           {(record.expands?.metrics || []).length > 0 &&
             ['int', 'long', 'float', 'double', 'string', 'boolean', 'date'].includes(
             ['int', 'long', 'float', 'double', 'string', 'boolean', 'date'].includes(
@@ -119,6 +127,22 @@ const Property = (props: Props) => {
                   <ClockCircleOutlined />
                   <ClockCircleOutlined />
                 </a>
                 </a>
               </Tooltip>
               </Tooltip>
+              // <PermissionButton
+              //   type={'link'}
+              //   onClick={() => {
+              //     setVisible(true);
+              //     setCurrentInfo(record);
+              //   }}
+              //   tooltip={{
+              //     placement: "top",
+              //     title: devicePermission.update ? "指标" : '暂无权限,请联系管理员'
+              //   }}
+              //   style={{ padding: 0 }}
+              //   key={'edit'}
+              //   isPermission={devicePermission.update}
+              // >
+              //   <ClockCircleOutlined />
+              // </PermissionButton>
             )}
             )}
           {record.expands?.type?.includes('read') && (
           {record.expands?.type?.includes('read') && (
             <Tooltip placement="top" title="获取最新属性值">
             <Tooltip placement="top" title="获取最新属性值">

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

@@ -274,6 +274,8 @@ const Cascade = () => {
               if (resp?.status === 200) {
               if (resp?.status === 200) {
                 onlyMessage('操作成功!');
                 onlyMessage('操作成功!');
                 actionRef.current?.reset?.();
                 actionRef.current?.reset?.();
+              } else {
+                onlyMessage('操作失败!', 'error');
               }
               }
             },
             },
           }}
           }}

+ 4 - 1
src/pages/notice/Config/Detail/index.tsx

@@ -695,7 +695,10 @@ const Detail = observer(() => {
         'x-decorator': 'FormItem',
         'x-decorator': 'FormItem',
         'x-component': 'Input.TextArea',
         'x-component': 'Input.TextArea',
         'x-component-props': {
         'x-component-props': {
-          rows: 4,
+          rows: 5,
+          placeholder: '请输入说明',
+          showCount: true,
+          maxLength: 200,
         },
         },
         'x-validator': [
         'x-validator': [
           {
           {

+ 7 - 4
src/pages/notice/Template/Detail/index.tsx

@@ -174,7 +174,7 @@ const Detail = observer(() => {
               state1.dataSource = typeList[value];
               state1.dataSource = typeList[value];
             });
             });
           });
           });
-          onFieldValueChange('provider', (field, form1) => {
+          onFieldValueChange('provider', async (field, form1) => {
             const value = field.value;
             const value = field.value;
             if (field.modified) {
             if (field.modified) {
               form1.setValuesIn('configId', null);
               form1.setValuesIn('configId', null);
@@ -182,10 +182,10 @@ const Detail = observer(() => {
             }
             }
             const _type = field.query('type').value();
             const _type = field.query('type').value();
             // 设置绑定配置的数据
             // 设置绑定配置的数据
+            const _list = await getConfig(_type, value);
             form1.setFieldState('configId', async (state1) => {
             form1.setFieldState('configId', async (state1) => {
-              state1.dataSource = await getConfig(_type, value);
+              state1.dataSource = _list;
             });
             });
-            console.log(_type, value);
             if (_type === 'email') {
             if (_type === 'email') {
               setProviderItem('embedded');
               setProviderItem('embedded');
             } else {
             } else {
@@ -1637,7 +1637,10 @@ const Detail = observer(() => {
         'x-decorator': 'FormItem',
         'x-decorator': 'FormItem',
         'x-component': 'Input.TextArea',
         'x-component': 'Input.TextArea',
         'x-component-props': {
         'x-component-props': {
-          rows: 4,
+          rows: 5,
+          placeholder: '请输入说明',
+          showCount: true,
+          maxLength: 200,
         },
         },
         'x-validator': [
         'x-validator': [
           {
           {

+ 2 - 0
src/pages/rule-engine/Instance/Save/index.tsx

@@ -74,6 +74,8 @@ const Save = (props: Props) => {
         'x-component-props': {
         'x-component-props': {
           rows: 5,
           rows: 5,
           placeholder: '请输入说明',
           placeholder: '请输入说明',
+          showCount: true,
+          maxLength: 200,
         },
         },
         'x-validator': [
         'x-validator': [
           {
           {