xieyonghong 3 anni fa
parent
commit
60903e6703
24 ha cambiato i file con 400 aggiunte e 200 eliminazioni
  1. 1 1
      src/components/FMonacoEditor/index.tsx
  2. 1 1
      src/components/ProTableCard/CardItems/Scene/index.tsx
  3. 18 9
      src/components/ProTableCard/index.tsx
  4. 1 0
      src/pages/DataCollect/Collector/components/Device/Save/index.tsx
  5. 2 2
      src/pages/DataCollect/Collector/components/Device/index.tsx
  6. 68 56
      src/pages/DataCollect/Collector/components/Point/CollectorCard/WritePoint.tsx
  7. 18 10
      src/pages/DataCollect/Collector/components/Tree/index.tsx
  8. 4 0
      src/pages/device/Instance/Detail/Functions/AdvancedMode.tsx
  9. 9 7
      src/pages/device/Instance/Detail/MetadataLog/Property/index.tsx
  10. 56 23
      src/pages/device/Instance/Detail/Running/Property/FileComponent/index.tsx
  11. 20 7
      src/pages/iot-card/Recharge/index.tsx
  12. 1 1
      src/pages/link/AccessConfig/service.ts
  13. 13 3
      src/pages/notice/Config/Debug/index.tsx
  14. 19 7
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/device/Tag.tsx
  15. 11 0
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/device/index.less
  16. 10 5
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/device/index.tsx
  17. 14 2
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/index.tsx
  18. 13 1
      src/pages/rule-engine/Scene/Save/action/notify/components/variableItem/inputFile.tsx
  19. 7 7
      src/pages/system/Apply/index.tsx
  20. 5 3
      src/pages/system/Department/Assets/deivce/index.tsx
  21. 5 3
      src/pages/system/Department/Assets/product/index.tsx
  22. 1 0
      src/pages/system/Department/Tree/tree.tsx
  23. 89 50
      src/pages/system/Menu/Setting/baseMenu.ts
  24. 14 2
      src/pages/system/Platforms/Api/basePage.tsx

+ 1 - 1
src/components/FMonacoEditor/index.tsx

@@ -47,7 +47,7 @@ export const JMonacoEditor = (props: Props) => {
             }
           }}
           {...props}
-          options={{ wordWrap: 'on' }}
+          options={{ wordWrap: 'on', automaticLayout: true }}
           editorDidMount={editorDidMountHandle}
         />
       )}

+ 1 - 1
src/components/ProTableCard/CardItems/Scene/index.tsx

@@ -85,7 +85,7 @@ const deviceRender = (data: ActionsType | undefined) => {
       return `${data?.options?.type}${data?.options?.name}${data?.options?.properties}`;
     case 'tag':
       let tags: string = '';
-      data.options?.taglist.map((item: any) => {
+      data.options?.taglist?.map((item: any) => {
         tags += item.type || '' + item.name || '' + item.value || '';
       });
       return `${

+ 18 - 9
src/components/ProTableCard/index.tsx

@@ -237,15 +237,16 @@ const ProTableCard = <
               resp = await request(newParam, sort, filter);
             }
             setLoading(false);
-            setTotal(resp.result ? resp.result.total : 0);
+            const result = {
+              data: resp.result ? resp.result.data : [],
+              pageIndex: resp.result ? resp.result.pageIndex : 0,
+              pageSize: resp.result ? resp.result.pageSize : 0,
+              total: resp.result ? resp.result.total : 0,
+            };
+            setTotal(result.total);
             return {
               code: resp.message,
-              result: {
-                data: resp.result ? resp.result.data : [],
-                pageIndex: resp.result ? resp.result.pageIndex : 0,
-                pageSize: resp.result ? resp.result.pageSize : 0,
-                total: resp.result ? resp.result.total : 0,
-              },
+              result,
               status: resp.status,
             };
           }
@@ -319,9 +320,17 @@ const ProTableCard = <
               pageSizeOptions={pageSizeOptions}
               pageSize={pageSize}
               showTotal={(num) => {
-                const minSize = pageIndex * pageSize + 1;
                 const MaxSize = (pageIndex + 1) * pageSize;
-                return `第 ${minSize} - ${MaxSize > num ? num : MaxSize} 条/总共 ${num} 条`;
+                const max = MaxSize > num ? num : MaxSize;
+
+                const minSize = pageIndex * pageSize + 1;
+                const pageIndexInt =
+                  parseInt(num / pageSize) === num / pageSize
+                    ? num / pageSize - 1
+                    : parseInt(num / pageSize);
+                const min = minSize > num ? pageIndexInt * pageSize + 1 : minSize;
+
+                return `第 ${min} - ${max} 条/总共 ${num} 条`;
               }}
             />
           )}

+ 1 - 0
src/pages/DataCollect/Collector/components/Device/Save/index.tsx

@@ -127,6 +127,7 @@ export default (props: Props) => {
             'x-component-props': {
               placeholder: '请选择所属通道',
             },
+            'x-disabled': !!props.data?.id,
             'x-validator': [
               {
                 required: true,

+ 2 - 2
src/pages/DataCollect/Collector/components/Device/index.tsx

@@ -415,8 +415,8 @@ export default observer((props: Props) => {
       {CollectorModel.visible && (
         <Save
           data={CollectorModel.current}
-          channelId={props.id}
-          provider={props.provider || CollectorModel.current?.provider}
+          // channelId={props.id}
+          // provider={props.provider || CollectorModel.current?.provider}
           close={() => {
             CollectorModel.visible = false;
           }}

+ 68 - 56
src/pages/DataCollect/Collector/components/Point/CollectorCard/WritePoint.tsx

@@ -34,62 +34,74 @@ const WritePoint = (props: Props) => {
       createForm({
         effects() {
           onFormInit((f) => {
-            let valueType: string =
-              props.data?.provider === 'OPC_UA'
-                ? props?.data?.configuration?.type || 'Number'
-                : props.data?.configuration?.codec?.provider || 'int8';
-            valueType = valueType.toLocaleLowerCase();
-            switch (valueType) {
-              case 'boolean':
-                f.setFieldState('propertyValue', async (state) => {
-                  state.dataSource = [
-                    {
-                      label: '是',
-                      value: true,
-                    },
-                    {
-                      label: '否',
-                      value: false,
-                    },
-                  ];
-                  state.componentProps = {
-                    placeholder: '请选择',
-                  };
-                  state.componentType = 'Select';
-                });
-                break;
-              case 'int8':
-              case 'int16':
-              case 'int32':
-              case 'int64':
-              case 'ieee754_float':
-              case 'ieee754_double':
-              case 'hex':
-              case 'number':
-                f.setFieldState('propertyValue', (state) => {
-                  state.componentType = 'NumberPicker';
-                  state.componentProps = {
-                    placeholder: '请输入',
-                  };
-                });
-                break;
-              case 'date':
-                f.setFieldState('propertyValue', (state) => {
-                  state.componentType = 'DatePicker';
-                  state.componentProps = {
-                    placeholder: '请选择',
-                    format: 'YYYY-MM-DD HH:mm:ss',
-                  };
-                });
-                break;
-              default:
-                f.setFieldState('propertyValue', (state) => {
-                  state.componentType = 'Input';
-                  state.componentProps = {
-                    placeholder: '请输入',
-                  };
-                });
-                break;
+            if (
+              props.data?.provider === 'MODBUS_TCP' &&
+              props.data?.configuration.function === 'Coils'
+            ) {
+              f.setFieldState('propertyValue', (state) => {
+                state.componentType = 'Input.TextArea';
+                state.componentProps = {
+                  placeholder: '请输入',
+                };
+              });
+            } else {
+              let valueType: string =
+                props.data?.provider === 'OPC_UA'
+                  ? props?.data?.configuration?.type || 'Number'
+                  : props.data?.configuration?.codec?.provider || 'int8';
+              valueType = valueType.toLocaleLowerCase();
+              switch (valueType) {
+                case 'boolean':
+                  f.setFieldState('propertyValue', async (state) => {
+                    state.dataSource = [
+                      {
+                        label: '是',
+                        value: true,
+                      },
+                      {
+                        label: '否',
+                        value: false,
+                      },
+                    ];
+                    state.componentProps = {
+                      placeholder: '请选择',
+                    };
+                    state.componentType = 'Select';
+                  });
+                  break;
+                case 'int8':
+                case 'int16':
+                case 'int32':
+                case 'int64':
+                case 'ieee754_float':
+                case 'ieee754_double':
+                case 'hex':
+                case 'number':
+                  f.setFieldState('propertyValue', (state) => {
+                    state.componentType = 'NumberPicker';
+                    state.componentProps = {
+                      placeholder: '请输入',
+                    };
+                  });
+                  break;
+                case 'date':
+                  f.setFieldState('propertyValue', (state) => {
+                    state.componentType = 'DatePicker';
+                    state.componentProps = {
+                      placeholder: '请选择',
+                      format: 'YYYY-MM-DD HH:mm:ss',
+                    };
+                  });
+                  break;
+                default:
+                  f.setFieldState('propertyValue', (state) => {
+                    state.componentType = 'Input';
+                    state.componentProps = {
+                      placeholder: '请输入',
+                    };
+                  });
+                  break;
+              }
             }
           });
         },

+ 18 - 10
src/pages/DataCollect/Collector/components/Tree/index.tsx

@@ -48,13 +48,17 @@ export default observer((props: Props) => {
       .queryCollector({ ...params, paging: false, sorts: [{ name: 'createTime', order: 'desc' }] })
       .then((resp) => {
         if (resp.status === 200) {
-          TreeModel.dataSource = [
-            {
-              id: '*',
-              name: '全部',
-              children: resp.result,
-            },
-          ];
+          if (params.terms) {
+            TreeModel.dataSource = resp.result;
+          } else {
+            TreeModel.dataSource = [
+              {
+                id: '*',
+                name: '全部',
+                children: resp.result,
+              },
+            ];
+          }
           props.change(TreeModel.dataSource[0]);
         }
         TreeModel.loading = false;
@@ -95,9 +99,13 @@ export default observer((props: Props) => {
           placeholder="请输入名称"
           allowClear
           onSearch={(val) => {
-            TreeModel.param = {
-              terms: [{ column: 'name', value: `%${val}%`, termType: 'like' }],
-            };
+            if (val) {
+              TreeModel.param = {
+                terms: [{ column: 'name', value: `%${val}%`, termType: 'like' }],
+              };
+            } else {
+              TreeModel.param = {};
+            }
           }}
           style={{ width: '100%' }}
         />

+ 4 - 0
src/pages/device/Instance/Detail/Functions/AdvancedMode.tsx

@@ -86,6 +86,10 @@ export default (props: FunctionProps) => {
     handleData(props.data);
   }, [props.data]);
 
+  useEffect(() => {
+    monacoRef.current?.layout();
+  });
+
   return (
     <div className="device-function-content">
       <div className="left">

+ 9 - 7
src/pages/device/Instance/Detail/MetadataLog/Property/index.tsx

@@ -15,7 +15,7 @@ import type { PropertyMetadata } from '@/pages/device/Product/typings';
 import encodeQuery from '@/utils/encodeQuery';
 import { useEffect, useState } from 'react';
 import moment from 'moment';
-import FileComponent from '../../Running/Property/FileComponent';
+import FileComponent, { getType } from '../../Running/Property/FileComponent';
 import { DownloadOutlined, SearchOutlined } from '@ant-design/icons';
 import Detail from './Detail';
 import AMap from './AMap';
@@ -69,22 +69,24 @@ const PropertyLog = (props: Props) => {
       dataIndex: 'action',
       key: 'action',
       render: (text: any, record: any) => [
-        data.valueType?.type === 'file' ? (
+        (data.valueType?.type === 'file' && data?.valueType?.fileType === 'Binary(二进制)') ||
+        (!getType(record?.value) && data?.valueType?.fileType === 'base64') ? (
           <a style={{ marginRight: 20 }}>
             <ATooltip title="下载">
               <DownloadOutlined
                 onClick={() => {
-                  const type = (record?.value || '').split('.').pop();
-                  const downloadUrl = record.value;
                   const downNode = document.createElement('a');
-                  downNode.href = downloadUrl;
-                  downNode.target = '_blank';
                   downNode.download = `${InstanceModel.detail.name}-${data.name}${moment(
                     new Date().getTime(),
-                  ).format('YYYY-MM-DD-HH-mm-ss')}.${type}`;
+                  ).format('YYYY-MM-DD-HH-mm-ss')}.txt`;
                   downNode.style.display = 'none';
+                  //字符串内容转成Blob地址
+                  const blob = new Blob([record.value]);
+                  downNode.href = URL.createObjectURL(blob);
+                  //触发点击
                   document.body.appendChild(downNode);
                   downNode.click();
+                  //移除
                   document.body.removeChild(downNode);
                 }}
               />

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

@@ -25,6 +25,27 @@ imgMap.set('video', require('/public/images/running/video.png'));
 imgMap.set('other', require('/public/images/running/other.png'));
 imgMap.set('obj', require('/public/images/running/obj.png'));
 
+const imgList = ['.jpg', '.png', '.swf', '.tiff'];
+const videoList = ['.m3u8', '.flv', '.mp4', '.rmvb', '.mvb'];
+const fileList = ['.txt', '.doc', '.xls', '.pdf', '.ppt', '.docx', '.xlsx', '.pptx'];
+
+export const getType = (url: string) => {
+  let t: string = '';
+  [...imgList, ...videoList, ...fileList].map((item) => {
+    const str = item.slice(1, item.length);
+    if (url.indexOf(str) !== -1) {
+      if (imgList.includes(item)) {
+        t = 'img';
+      } else if (videoList.includes(item)) {
+        t = 'video';
+      } else {
+        t = str;
+      }
+    }
+  });
+  return t;
+};
+
 const FileComponent = (props: Props) => {
   const { data, value } = props;
   const [type, setType] = useState<string>('other');
@@ -33,7 +54,7 @@ const FileComponent = (props: Props) => {
   const [temp, setTemp] = useState<boolean>(false);
 
   const renderFile = () => {
-    if (['.jpg', '.png', '.swf', '.tiff'].some((item) => value?.formatValue.includes(item))) {
+    if (imgList.some((item) => value?.formatValue.includes(item))) {
       // 图片
       return (
         <div
@@ -61,9 +82,7 @@ const FileComponent = (props: Props) => {
         </div>
       );
     }
-    if (
-      ['.m3u8', '.flv', '.mp4', '.rmvb', '.mvb'].some((item) => value?.formatValue.includes(item))
-    ) {
+    if (videoList.some((item) => value?.formatValue.includes(item))) {
       return (
         <div
           className={props.type === 'card' ? styles.cardValue : styles.otherValue}
@@ -83,15 +102,8 @@ const FileComponent = (props: Props) => {
           <img src={imgMap.get('video')} />
         </div>
       );
-    } else if (
-      ['.txt', '.doc', '.xls', '.pdf', '.ppt', '.docx', '.xlsx', '.pptx'].some((item) =>
-        value?.formatValue.includes(item),
-      )
-    ) {
-      const flag =
-        ['.txt', '.doc', '.xls', '.pdf', '.ppt', '.docx', '.xlsx', '.pptx'].find((item) =>
-          value?.formatValue.includes(item),
-        ) || '--';
+    } else if (fileList.some((item) => value?.formatValue.includes(item))) {
+      const flag = fileList.find((item) => value?.formatValue.includes(item)) || '--';
       return (
         <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>
           <img src={imgMap.get(flag.slice(1))} />
@@ -106,6 +118,28 @@ const FileComponent = (props: Props) => {
     }
   };
 
+  const base64Render = () => {
+    const _type = getType(value?.formatValue);
+    if (!!_type) {
+      return (
+        <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>
+          <img
+            src={imgMap.get(_type)}
+            onError={(e: any) => {
+              e.target.src = imgMap.get('other');
+            }}
+          />
+        </div>
+      );
+    } else {
+      return (
+        <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>
+          <img src={imgMap.get('other')} />
+        </div>
+      );
+    }
+  };
+
   const renderValue = () => {
     if (value?.formatValue !== 0 && !value?.formatValue) {
       return (
@@ -116,16 +150,15 @@ const FileComponent = (props: Props) => {
         data?.valueType?.fileType === 'base64' ||
         data?.valueType?.fileType === 'Binary(二进制)'
       ) {
-        return (
-          <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>
-            <img
-              src={value?.formatValue}
-              onError={(e: any) => {
-                e.target.src = imgMap.get('other');
-              }}
-            />
-          </div>
-        );
+        if (data?.valueType?.fileType === 'base64') {
+          return base64Render();
+        } else {
+          return (
+            <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>
+              <img src={imgMap.get('other')} />
+            </div>
+          );
+        }
       } else {
         return renderFile();
       }

+ 20 - 7
src/pages/iot-card/Recharge/index.tsx

@@ -4,7 +4,6 @@ import useDomFullHeight from '@/hooks/document/useDomFullHeight';
 import { ExclamationCircleOutlined, EyeOutlined } from '@ant-design/icons';
 import { PageContainer } from '@ant-design/pro-layout';
 import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { Tooltip } from 'antd';
 import moment from 'moment';
 import { useRef, useState } from 'react';
 import Service from '../CardManagement/service';
@@ -81,17 +80,31 @@ const Recharge = () => {
       width: 200,
       hideInSearch: true,
       render: (_, record) => [
-        <a
-          key="editable"
+        <PermissionButton
           onClick={() => {
             setDetail(true);
             setCurrent(record);
           }}
+          isPermission={permission.view}
+          key="view"
+          type="link"
+          tooltip={{
+            title: '查看',
+          }}
         >
-          <Tooltip title="查看">
-            <EyeOutlined />
-          </Tooltip>
-        </a>,
+          <EyeOutlined />
+        </PermissionButton>,
+        // <a
+        //   key="editable"
+        //   onClick={() => {
+        //     setDetail(true);
+        //     setCurrent(record);
+        //   }}
+        // >
+        //   <Tooltip title="查看">
+        //     <EyeOutlined />
+        //   </Tooltip>
+        // </a>,
       ],
     },
   ];

+ 1 - 1
src/pages/link/AccessConfig/service.ts

@@ -27,7 +27,7 @@ class Service extends BaseService<AccessItem> {
       method: 'GET',
     });
   public getNetworkList = (networkType: string, params?: any) =>
-    request(`/${SystemConst.API_BASE}/network/config/${networkType}/_detail`, {
+    request(`/${SystemConst.API_BASE}/network/config/${networkType}/_alive`, {
       method: 'GET',
       params,
     });

+ 13 - 3
src/pages/notice/Config/Debug/index.tsx

@@ -1,5 +1,5 @@
 import { Modal } from 'antd';
-import { useMemo, useRef } from 'react';
+import { useMemo, useRef, useState } from 'react';
 import { createForm, Field, onFieldReact, onFieldValueChange } from '@formily/core';
 import { createSchemaField, observer } from '@formily/react';
 import {
@@ -25,6 +25,7 @@ const Debug = observer(() => {
   // const location = useLocation<{ id: string }>();
   const id = state.current?.type; // (location as any).query?.id;
   const variableRef = useRef<any>([]);
+  const [loading, setLoading] = useState(false);
 
   const form = useMemo(
     () =>
@@ -44,6 +45,12 @@ const Debug = observer(() => {
                   state1.visible = true;
                   state1.value = _template?.variableDefinitions;
                 });
+              } else {
+                variableRef.current = [];
+                form1.setFieldState('variableDefinitions', (state1) => {
+                  state1.visible = true;
+                  state1.value = undefined;
+                });
               }
             });
 
@@ -162,6 +169,7 @@ const Debug = observer(() => {
       variableDefinitions: {
         title: '变量',
         type: 'string',
+        required: true,
         'x-decorator': 'FormItem',
         'x-component': 'ArrayTable',
         'x-component-props': {
@@ -230,7 +238,7 @@ const Debug = observer(() => {
     const templateId = data.templateId;
     // const list = Store.get('notice-template-list');
     // const _template = list.find((item: any) => item.id === templateId);
-
+    setLoading(true);
     const resp = await service.debug(
       state?.current.id,
       templateId,
@@ -248,8 +256,9 @@ const Debug = observer(() => {
     );
     if (resp.status === 200) {
       onlyMessage('操作成功!');
-      state.debug = false;
     }
+    state.debug = false;
+    setLoading(false);
   };
   return (
     <Modal
@@ -258,6 +267,7 @@ const Debug = observer(() => {
       visible={state.debug}
       onCancel={() => (state.debug = false)}
       onOk={start}
+      confirmLoading={loading}
     >
       <Form form={form} layout={'vertical'}>
         <SchemaField schema={schema} scope={{ getTemplate, useAsyncDataSource }} />

+ 19 - 7
src/pages/rule-engine/Scene/Save/action/DeviceOutput/device/Tag.tsx

@@ -2,6 +2,7 @@ import { Button, Col, DatePicker, Input, InputNumber, Row, Select, Space } from
 import { useEffect, useState } from 'react';
 import moment from 'moment';
 import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
+import './index.less';
 
 interface TagModalProps {
   tagData: any[];
@@ -98,6 +99,9 @@ export default (props: TagModalProps) => {
             placeholder={'请选择' + name}
             onChange={(key) => {
               record.value = key;
+              if (key) {
+                onChange();
+              }
             }}
           />
         );
@@ -113,6 +117,9 @@ export default (props: TagModalProps) => {
             placeholder={'请选择' + name}
             onChange={(key) => {
               record.value = key;
+              if (key) {
+                onChange();
+              }
             }}
           />
         );
@@ -127,6 +134,9 @@ export default (props: TagModalProps) => {
             placeholder={'请输入' + name}
             onChange={(key) => {
               record.value = key;
+              if (key) {
+                onChange();
+              }
             }}
           />
         );
@@ -141,6 +151,9 @@ export default (props: TagModalProps) => {
                 style={{ width: '100%' }}
                 onChange={(_, date) => {
                   record.value = date;
+                  if (date) {
+                    onChange();
+                  }
                 }}
               />
             }
@@ -152,7 +165,10 @@ export default (props: TagModalProps) => {
             value={record.value}
             placeholder={'请输入标签值'}
             onChange={(e) => {
-              record.value = e.target.value;
+              if (type && e.target.value) {
+                record.value = e.target.value;
+                onChange();
+              }
             }}
           />
         );
@@ -161,16 +177,12 @@ export default (props: TagModalProps) => {
 
   return (
     <>
-      <div
-        onChange={() => {
-          onChange();
-        }}
-      >
+      <div>
         {tagList.map((tag, index) => (
           <Row gutter={12} key={tag.id || index} style={{ marginBottom: 12 }}>
             <Col span={4}>
               {index === 0 ? (
-                <span>标签选择</span>
+                <span className="tagName">标签选择</span>
               ) : (
                 <Select
                   value={tag.type}

+ 11 - 0
src/pages/rule-engine/Scene/Save/action/DeviceOutput/device/index.less

@@ -0,0 +1,11 @@
+.tagName::before {
+  position: relative;
+  left: 70px;
+  display: inline-block;
+  margin-right: 4px;
+  color: #ff4d4f;
+  font-size: 14px;
+  font-family: SimSun, sans-serif;
+  line-height: 1;
+  content: '*';
+}

+ 10 - 5
src/pages/rule-engine/Scene/Save/action/DeviceOutput/device/index.tsx

@@ -28,6 +28,7 @@ interface Props {
   thenName: number;
   branchGroup?: number;
   formProductId: any;
+  get: (ref: any) => void;
 }
 
 export default observer((props: Props) => {
@@ -404,11 +405,7 @@ export default observer((props: Props) => {
         );
       case 'tag':
         return (
-          <Form.Item
-            name="selectorValues"
-            // label='标签'
-            rules={[{ required: true, message: '请选择标签' }]}
-          >
+          <Form.Item name="selectorValues" rules={[{ required: true, message: '请选择标签' }]}>
             <Tag
               tagData={tagList}
               onChange={(value) => {
@@ -445,8 +442,12 @@ export default observer((props: Props) => {
   };
 
   useEffect(() => {
+    console.log(DeviceModel.selectorValues, '--------');
     if (form) {
       form.setFieldsValue({ selector: DeviceModel.selector });
+      if (DeviceModel.selectorValues) {
+        form.setFieldsValue({ selectorValues: DeviceModel.selectorValues });
+      }
     }
     sourceChangeEvent();
     if (DeviceModel.deviceId) {
@@ -481,6 +482,10 @@ export default observer((props: Props) => {
     DeviceModel.selector = selector;
   }, [selector]);
 
+  useEffect(() => {
+    props.get(form);
+  }, [form]);
+
   return (
     <div>
       <Form form={form} layout={'vertical'}>

+ 14 - 2
src/pages/rule-engine/Scene/Save/action/DeviceOutput/index.tsx

@@ -26,6 +26,7 @@ interface Props {
 
 export default observer((props: Props) => {
   const formRef = useRef<any>();
+  const tagFormRef = useRef<any>();
   const formProductIdRef = useRef<any>('');
 
   DeviceModel.steps = [
@@ -44,6 +45,9 @@ export default observer((props: Props) => {
           branchGroup={props.branchGroup}
           thenName={props.thenName}
           formProductId={formProductIdRef.current}
+          get={(item: any) => {
+            tagFormRef.current = item;
+          }}
         />
       ),
     },
@@ -62,12 +66,20 @@ export default observer((props: Props) => {
       ),
     },
   ];
-  const next = () => {
+  const next = async () => {
     if (
       (DeviceModel.current === 0 && DeviceModel.productId) ||
       (DeviceModel.current === 1 && (DeviceModel.deviceId || DeviceModel.selector === 'tag'))
     ) {
-      return (DeviceModel.current += 1);
+      if (DeviceModel.selector === 'tag') {
+        const value = await tagFormRef.current?.validateFields();
+        if (value) {
+          return (DeviceModel.current += 1);
+        }
+        console.log('----------', value);
+      } else {
+        return (DeviceModel.current += 1);
+      }
     } else {
       return DeviceModel.current === 0
         ? onlyMessage('请选择产品', 'error')

+ 13 - 1
src/pages/rule-engine/Scene/Save/action/notify/components/variableItem/inputFile.tsx

@@ -1,5 +1,5 @@
 import { useEffect, useState } from 'react';
-import { Button, Input, Upload } from 'antd';
+import { Button, Input, message, Upload } from 'antd';
 import { UploadChangeParam } from 'antd/lib/upload/interface';
 import SystemConst from '@/utils/const';
 import Token from '@/utils/token';
@@ -42,9 +42,21 @@ export default (props: InputUploadProps) => {
       headers={{
         'X-Access-Token': Token.get(),
       }}
+      accept={'image/jpeg,image/png'}
       showUploadList={false}
       onChange={handleChange}
       disabled={loading}
+      beforeUpload={(file) => {
+        const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
+        if (!isJpgOrPng) {
+          message.error('请上传正确格式图片');
+        }
+        const isSize = file.size / 1024 / 1024 < 4;
+        if (!isSize) {
+          message.error(`图片大小必须小于4M`);
+        }
+        return isJpgOrPng && isSize;
+      }}
     >
       <Button type={'link'} style={{ height: 30 }}>
         {loading ? <LoadingOutlined /> : <PlusOutlined />}

+ 7 - 7
src/pages/system/Apply/index.tsx

@@ -147,7 +147,7 @@ const Apply = () => {
         </PermissionButton>,
         isPage(record.integrationModes) ? (
           <PermissionButton
-            isPermission={permission.update}
+            isPermission={permission.update || permission.add}
             key="page"
             onClick={() => {
               setData(record);
@@ -167,7 +167,7 @@ const Apply = () => {
             key={'empowerment'}
             type={'link'}
             style={{ padding: 0 }}
-            isPermission={permission.empowerment}
+            isPermission={permission.update || permission.add}
             tooltip={{
               title: '赋权',
             }}
@@ -184,7 +184,7 @@ const Apply = () => {
             key={'api'}
             type={'link'}
             style={{ padding: 0 }}
-            isPermission={permission.api}
+            isPermission={permission.update || permission.add}
             tooltip={{
               title: '查看API',
             }}
@@ -197,7 +197,7 @@ const Apply = () => {
           </PermissionButton>
         ) : null,
         <PermissionButton
-          isPermission={permission.action}
+          isPermission={permission.update}
           key="action"
           type={'link'}
           style={{ padding: 0 }}
@@ -387,7 +387,7 @@ const Apply = () => {
                       {isPage(record.integrationModes) && (
                         <Menu.Item key="menu">
                           <PermissionButton
-                            isPermission={permission.update}
+                            isPermission={permission.update || permission.add}
                             key="edit"
                             onClick={() => {
                               setData(record);
@@ -410,7 +410,7 @@ const Apply = () => {
                             key={'empowerment'}
                             type={'link'}
                             style={{ padding: 0 }}
-                            isPermission={permission.empowerment}
+                            isPermission={permission.update || permission.add}
                             tooltip={{
                               title: '赋权',
                             }}
@@ -430,7 +430,7 @@ const Apply = () => {
                             key={'api'}
                             type={'link'}
                             style={{ padding: 0 }}
-                            isPermission={permission.api}
+                            isPermission={permission.update || permission.add}
                             tooltip={{
                               title: '查看API',
                             }}

+ 5 - 3
src/pages/system/Department/Assets/deivce/index.tsx

@@ -411,7 +411,8 @@ export default observer((props: { parentId: string }) => {
                   setPermissions(record.grantedPermissions!);
                   setUpdateVisible(true);
                 }}
-                isPermission={permission.edit}
+                // isPermission={permission.edit}
+                isPermission={permission.assert}
               >
                 <EditOutlined />
               </PermissionButton>,
@@ -433,7 +434,8 @@ export default observer((props: { parentId: string }) => {
                 onClick={(e) => {
                   e?.stopPropagation();
                 }}
-                isPermission={permission.bind}
+                // isPermission={permission.bind}
+                isPermission={permission.assert}
               >
                 <DisconnectOutlined />
               </PermissionButton>,
@@ -473,7 +475,7 @@ export default observer((props: { parentId: string }) => {
                 defaultMessage: '批量解绑',
               }),
             }}
-            isPermission={permission.bind}
+            isPermission={permission.assert}
           >
             {intl.formatMessage({
               id: 'pages.system.role.option.unBindUser',

+ 5 - 3
src/pages/system/Department/Assets/product/index.tsx

@@ -167,7 +167,8 @@ export default observer((props: { parentId: string }) => {
             setPermissions(record.grantedPermissions!);
             setUpdateVisible(true);
           }}
-          isPermission={permission.edit}
+          // isPermission={permission.edit}
+          isPermission={permission.assert}
         >
           <EditOutlined />
         </PermissionButton>,
@@ -183,7 +184,8 @@ export default observer((props: { parentId: string }) => {
               singleUnBind(record.id);
             },
           }}
-          isPermission={permission.bind}
+          // isPermission={permission.bind}
+          isPermission={permission.assert}
         >
           <DisconnectOutlined />
         </PermissionButton>,
@@ -475,7 +477,7 @@ export default observer((props: { parentId: string }) => {
                 defaultMessage: '批量解绑',
               }),
             }}
-            isPermission={permission.bind}
+            isPermission={permission.assert}
           >
             {intl.formatMessage({
               id: 'pages.system.role.option.unBindUser',

+ 1 - 0
src/pages/system/Department/Tree/tree.tsx

@@ -366,6 +366,7 @@ export default (props: TreeProps) => {
                           sortIndex: nodeData.children ? nodeData.children.length + 1 : 1,
                         });
                         setVisible(true);
+                        setTreeDataList(treeData);
                       }}
                     >
                       <PlusCircleOutlined />

+ 89 - 50
src/pages/system/Menu/Setting/baseMenu.ts

@@ -3023,54 +3023,54 @@ export default [
               },
             ],
           },
-          {
-            id: 'edit',
-            name: '资产编辑',
-            permissions: [
-              {
-                permission: 'assets-bind',
-                actions: ['query', 'permission'],
-              },
-              {
-                permission: 'user',
-                actions: ['query'],
-              },
-              {
-                permission: 'device-product',
-                actions: ['query'],
-              },
-              {
-                permission: 'device-instance',
-                actions: ['query'],
-              },
-            ],
-          },
-          {
-            id: 'bind',
-            name: '资产解绑',
-            permissions: [
-              {
-                permission: 'assets-bind',
-                actions: ['unbind', 'query'],
-              },
-              {
-                permission: 'user',
-                actions: ['query'],
-              },
-              {
-                permission: 'device-product',
-                actions: ['query'],
-              },
-              {
-                permission: 'device-instance',
-                actions: ['query'],
-              },
-              {
-                permission: 'organization',
-                actions: ['unbind-user'],
-              },
-            ],
-          },
+          // {
+          //   id: 'edit',
+          //   name: '资产编辑',
+          //   permissions: [
+          //     {
+          //       permission: 'assets-bind',
+          //       actions: ['query', 'permission'],
+          //     },
+          //     {
+          //       permission: 'user',
+          //       actions: ['query'],
+          //     },
+          //     {
+          //       permission: 'device-product',
+          //       actions: ['query'],
+          //     },
+          //     {
+          //       permission: 'device-instance',
+          //       actions: ['query'],
+          //     },
+          //   ],
+          // },
+          // {
+          //   id: 'bind',
+          //   name: '资产解绑',
+          //   permissions: [
+          //     {
+          //       permission: 'assets-bind',
+          //       actions: ['unbind', 'query'],
+          //     },
+          //     {
+          //       permission: 'user',
+          //       actions: ['query'],
+          //     },
+          //     {
+          //       permission: 'device-product',
+          //       actions: ['query'],
+          //     },
+          //     {
+          //       permission: 'device-instance',
+          //       actions: ['query'],
+          //     },
+          //     {
+          //       permission: 'organization',
+          //       actions: ['unbind-user'],
+          //     },
+          //   ],
+          // },
           {
             id: 'bind-user',
             name: '绑定用户',
@@ -3099,7 +3099,7 @@ export default [
           },
           {
             id: 'assert',
-            name: '分配资产',
+            name: '资产分配',
             permissions: [
               {
                 permission: 'assets-bind',
@@ -3637,7 +3637,28 @@ export default [
         icon: 'icon-chakanAPI',
         showPage: ['open-api'],
         permissions: [{ permission: 'open-api', actions: ['query', 'save'] }],
-        buttons: [],
+        buttons: [
+          {
+            id: 'view',
+            name: '查看',
+            permissions: [
+              {
+                permission: 'open-api',
+                actions: ['query'],
+              },
+            ],
+          },
+          {
+            id: 'update',
+            name: '编辑',
+            permissions: [
+              {
+                permission: 'open-api',
+                actions: ['query', 'save'],
+              },
+            ],
+          },
+        ],
       },
       {
         code: 'system/Apply',
@@ -3677,6 +3698,10 @@ export default [
                 permission: 'role',
                 actions: ['query'],
               },
+              {
+                permission: 'open-api',
+                actions: ['query', 'save', 'delete'],
+              },
             ],
           },
           {
@@ -3695,6 +3720,10 @@ export default [
                 permission: 'role',
                 actions: ['query'],
               },
+              {
+                permission: 'open-api',
+                actions: ['query', 'save', 'delete'],
+              },
             ],
           },
           {
@@ -3978,6 +4007,16 @@ export default [
               },
             ],
           },
+          {
+            id: 'view',
+            name: '查看',
+            permissions: [
+              {
+                permission: 'network-card',
+                actions: ['query'],
+              },
+            ],
+          },
         ],
       },
       {

+ 14 - 2
src/pages/system/Platforms/Api/basePage.tsx

@@ -4,6 +4,7 @@ import { useLocation } from 'umi';
 import { service } from '../index';
 import { ApiModel } from '@/pages/system/Platforms/Api/base';
 import { onlyMessage } from '@/utils/util';
+import PermissionButton from '@/components/PermissionButton';
 
 interface TableProps {
   data: any;
@@ -21,6 +22,7 @@ export default (props: TableProps) => {
   const [dataSource, setDataSource] = useState<any[]>([]);
   const [loading, setLoading] = useState(false);
   const [GrantKeys, setGrantKeys] = useState<string[] | undefined>(undefined);
+  const { permission } = PermissionButton.usePermission('system/Platforms/Setting');
 
   const grantCache = useRef<string[]>([]);
 
@@ -207,9 +209,19 @@ export default (props: TableProps) => {
       />
       {props.isShowGranted !== true && (
         <div className={'platforms-api-save'}>
-          <Button type={'primary'} onClick={save} loading={loading}>
+          <PermissionButton
+            isPermission={permission.update}
+            onClick={save}
+            key={'update'}
+            type={'primary'}
+            style={{ padding: 0, width: 50 }}
+            loading={loading}
+          >
             保存
-          </Button>
+          </PermissionButton>
+          {/* <Button type={'primary'} onClick={save} >
+            保存
+          </Button> */}
         </div>
       )}
     </div>