Przeglądaj źródła

fix: 修改bug12.19

100011797 3 lat temu
rodzic
commit
57a66f41a5

+ 2 - 1
src/components/ProTableCard/CardItems/AccessConfig/index.tsx

@@ -15,6 +15,7 @@ export interface AccessConfigCardProps extends AccessItem {
   avatarSize?: number;
   showTool?: boolean;
   activeStyle?: string;
+  showMask?: boolean;
 }
 
 const defaultImage = require('/public/images/device-access.png');
@@ -22,7 +23,7 @@ const defaultImage = require('/public/images/device-access.png');
 export default (props: AccessConfigCardProps) => {
   return (
     <TableCard
-      // showMask={false}
+      showMask={props.showMask}
       detail={props.detail}
       actions={props.actions}
       status={props.state.value}

+ 3 - 3
src/pages/device/Firmware/index.tsx

@@ -4,14 +4,14 @@ import ProTable from '@jetlinks/pro-table';
 import { message, Popconfirm } from 'antd';
 import { useRef, useState } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
-import { DeleteOutlined, EditOutlined, NodeExpandOutlined, PlusOutlined } from '@ant-design/icons';
+import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons';
 import { useHistory } from 'umi';
 import { model } from '@formily/reactive';
 import { observer } from '@formily/react';
 import type { FirmwareItem } from '@/pages/device/Firmware/typings';
 import Service from '@/pages/device/Firmware/service';
 import Save from '@/pages/device/Firmware/Save';
-import { PermissionButton } from '@/components';
+import { AIcon, PermissionButton } from '@/components';
 import useDomFullHeight from '@/hooks/document/useDomFullHeight';
 import usePermissions from '@/hooks/permission';
 import SearchComponent from '@/components/SearchComponent';
@@ -139,7 +139,7 @@ const Firmware = observer(() => {
             title: '升级任务',
           }}
         >
-          <NodeExpandOutlined />
+          <AIcon type={'icon-tongzhijilu'} />
         </PermissionButton>,
         <PermissionButton
           style={{ padding: 0 }}

+ 18 - 1
src/pages/device/Instance/Detail/ChildDevice/BindChildDevice/index.tsx

@@ -178,7 +178,24 @@ const BindChildDevice = (props: Props) => {
         pagination={{
           pageSize: 10,
         }}
-        request={(params) => service.query({ ...params })}
+        request={(params) =>
+          service.query({
+            ...params,
+            terms: [
+              ...(params?.terms || []),
+              {
+                terms: [
+                  {
+                    termType: 'eq',
+                    column: 'deviceType',
+                    value: 'childrenDevice',
+                  },
+                ],
+                type: 'and',
+              },
+            ],
+          })
+        }
       />
     </Modal>
   );

+ 9 - 4
src/pages/device/Instance/Detail/Diagnose/Message/form.tsx

@@ -4,6 +4,7 @@ import { DatePicker, Input, InputNumber, Select, Tooltip } from 'antd';
 import { GeoPoint, MetadataJsonInput } from '@/components';
 import { EditableProTable, ProColumns } from '@jetlinks/pro-table';
 import { QuestionCircleOutlined } from '@ant-design/icons';
+import { DiagnoseMessageModel } from '@/pages/device/Instance/Detail/Diagnose/Message/index';
 
 type DiagnoseFormProps = {
   data: any[];
@@ -173,6 +174,10 @@ const DiagnoseForm = forwardRef((props: DiagnoseFormProps, ref) => {
     },
   ];
 
+  useEffect(() => {
+    formRef.current?.setFieldsValue(DiagnoseMessageModel._inputs);
+  }, [props.data]);
+
   const handleDataSource = (data: any) => {
     const array = [];
     for (const datum of data) {
@@ -184,7 +189,7 @@ const DiagnoseForm = forwardRef((props: DiagnoseFormProps, ref) => {
         format: datum.valueType ? datum.valueType.format : undefined,
         options: datum.valueType ? datum.valueType.elements : undefined,
         json: type === 'object' ? datum?.json?.properties?.[0] : undefined,
-        value: undefined,
+        value: DiagnoseMessageModel._inputs?.[datum.id] || undefined,
       });
     }
     setEditableRowKeys(array.map((d) => d.id));
@@ -193,15 +198,15 @@ const DiagnoseForm = forwardRef((props: DiagnoseFormProps, ref) => {
     });
   };
 
-  /**
-   * 执行
-   */
   const actionRun = () => {
     return new Promise(async (resolve) => {
       const formData = await formRef.current?.validateFields().catch(() => {
         resolve(false);
       });
       if (formData?.table) {
+        (formData?.table || []).forEach((item: any) => {
+          DiagnoseMessageModel._inputs[item.id] = item.value;
+        });
         resolve(formData.table);
       } else {
         resolve(false);

+ 36 - 16
src/pages/device/Instance/Detail/Diagnose/Message/index.tsx

@@ -2,7 +2,7 @@ import TitleComponent from '@/components/TitleComponent';
 import './index.less';
 import Dialog from './Dialog';
 import { Badge, Button, Col, Empty, Row } from 'antd';
-import { useEffect, useMemo, useRef, useState } from 'react';
+import { useEffect, useMemo, useRef } from 'react';
 import { InstanceModel, service } from '@/pages/device/Instance';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
 import { map } from 'rxjs/operators';
@@ -24,11 +24,24 @@ import Log from './Log';
 import { DiagnoseStatusModel, messageStatusMap, messageStyleMap } from '../Status/model';
 import { observer } from '@formily/reactive-react';
 import DiagnoseForm from './form';
+import { model } from '@formily/reactive';
+
+export const DiagnoseMessageModel = model<{
+  input: any;
+  inputs: any[];
+  data: any;
+  _inputs: any;
+}>({
+  input: {},
+  inputs: [],
+  data: {
+    type: 'function',
+  },
+  _inputs: {},
+});
 
 const Message = observer(() => {
   const [subscribeTopic] = useSendWebsocketMessage();
-  const [input, setInput] = useState<any>({});
-  const [inputs, setInputs] = useState<any[]>([]);
   const DiagnoseFormRef = useRef<{ save: any }>();
 
   const metadata = JSON.parse(InstanceModel.detail?.metadata || '{}');
@@ -120,9 +133,7 @@ const Message = observer(() => {
   const _form = useMemo(
     () =>
       createForm({
-        initialValues: {
-          type: 'function',
-        },
+        initialValues: DiagnoseMessageModel.data,
         effects() {
           onFieldValueChange('property', (field) => {
             const value = (field as Field).value;
@@ -166,12 +177,16 @@ const Message = observer(() => {
           });
           onFieldValueChange('function', (field) => {
             const value = (field as Field).value;
-            setInputs([]);
-            setInput({});
+            // setInputs([]);
+            // setInput({});
+            DiagnoseMessageModel.inputs = [];
+            DiagnoseMessageModel.input = {};
             if (value) {
               const data = (metadata?.functions || []).find((item: any) => item.id === value);
-              setInput(data);
-              setInputs(data?.inputs || []);
+              // setInput(data);
+              // setInputs(data?.inputs || []);
+              DiagnoseMessageModel.inputs = data?.inputs || [];
+              DiagnoseMessageModel.input = data;
             }
           });
         },
@@ -373,8 +388,9 @@ const Message = observer(() => {
                   className={'function-item-btn'}
                   onClick={async () => {
                     const values = await _form.submit<any>();
+                    DiagnoseMessageModel.data = values;
                     let _inputs = undefined;
-                    if (inputs.length) {
+                    if (DiagnoseMessageModel.inputs.length) {
                       _inputs = await DiagnoseFormRef.current?.save();
                       if (!_inputs) {
                         return;
@@ -386,9 +402,13 @@ const Message = observer(() => {
                       list.map((it: any) => {
                         obj[it.id] = it.value;
                       });
-                      await service.executeFunctions(InstanceModel.detail?.id || '', input.id, {
-                        ...obj,
-                      });
+                      await service.executeFunctions(
+                        InstanceModel.detail?.id || '',
+                        DiagnoseMessageModel?.input?.id,
+                        {
+                          ...obj,
+                        },
+                      );
                     } else {
                       if (values.propertyType === 'read') {
                         await service.readProperties(InstanceModel.detail?.id || '', [
@@ -405,10 +425,10 @@ const Message = observer(() => {
                   发送
                 </Button>
               </div>
-              {inputs.length > 0 && (
+              {DiagnoseMessageModel?.inputs?.length > 0 && (
                 <div className="inputs-parameter">
                   <h4>功能参数</h4>
-                  <DiagnoseForm data={inputs} ref={DiagnoseFormRef} />
+                  <DiagnoseForm data={DiagnoseMessageModel.inputs} ref={DiagnoseFormRef} />
                 </div>
               )}
             </div>

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

@@ -1,6 +1,6 @@
 import { Card, Progress } from 'antd';
 import { useEffect, useState } from 'react';
-import Message from './Message';
+import Message, { DiagnoseMessageModel } from './Message';
 import Status from './Status';
 import './index.less';
 import { useDomFullHeight } from '@/hooks';
@@ -51,6 +51,12 @@ const Diagnose = observer(() => {
       DiagnoseStatusModel.status = 'loading';
       DiagnoseStatusModel.state = 'loading';
       DiagnoseStatusModel.flag = false;
+      DiagnoseMessageModel.inputs = [];
+      DiagnoseMessageModel.data = { type: 'function' };
+      DiagnoseMessageModel.input = {};
+      DiagnoseMessageModel._inputs = {};
+      DiagnoseStatusModel.logList = [];
+      DiagnoseStatusModel.dialogList = [];
     };
   }, [InstanceModel.active]);
 
@@ -121,7 +127,7 @@ const Diagnose = observer(() => {
               }}
             >
               {i.text}
-              {current === i.key ? '(诊断中)' : ''}
+              {/*{current === i.key ? '(诊断中)' : ''}*/}
             </div>
           ))}
         </div>

+ 21 - 2
src/pages/device/Instance/Detail/Info/index.tsx

@@ -1,12 +1,12 @@
 import { Card, Descriptions } from 'antd';
-import { InstanceModel } from '@/pages/device/Instance';
+import { InstanceModel, service } from '@/pages/device/Instance';
 import moment from 'moment';
 import { observer } from '@formily/react';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import Config from '@/pages/device/Instance/Detail/Config';
 import Reation from '@/pages/device/Instance/Detail/Reation';
 import Save from '../../Save';
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
 import type { DeviceInstance } from '../../typings';
 import { EditOutlined } from '@ant-design/icons';
 import Tags from '@/pages/device/Instance/Detail/Tags';
@@ -18,6 +18,20 @@ const Info = observer(() => {
   const [visible, setVisible] = useState<boolean>(false);
   const { permission } = PermissionButton.usePermission('device/Instance');
   const { minHeight } = useDomFullHeight(`.device-detail-body`);
+  const [parent, setParent] = useState<Partial<DeviceInstance>>({});
+
+  useEffect(() => {
+    if (
+      InstanceModel.detail?.deviceType?.value === 'childrenDevice' &&
+      InstanceModel.detail?.parentId
+    ) {
+      service.detail(InstanceModel.detail?.parentId).then((resp) => {
+        if (resp.status === 200) {
+          setParent(resp.result);
+        }
+      });
+    }
+  }, [InstanceModel.detail?.parentId]);
 
   return (
     <>
@@ -144,6 +158,11 @@ const Info = observer(() => {
               ? moment(InstanceModel.detail?.onlineTime).format('YYYY-MM-DD HH:mm:ss')
               : ''}
           </Descriptions.Item>
+          {InstanceModel.detail?.deviceType?.value === 'childrenDevice' && (
+            <Descriptions.Item label={'父设备'}>
+              {parent?.name || InstanceModel.detail?.parentId}
+            </Descriptions.Item>
+          )}
           <Descriptions.Item
             label={intl.formatMessage({
               id: 'pages.table.description',

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

@@ -17,8 +17,8 @@ const Detail = (props: Props) => {
     } else if (['.flv', '.m3u8', '.mp4'].includes(type)) {
       return <LivePlayer live={false} url={value?.formatValue} />;
     } else if (type === 'obj') {
-      // @ts-ignore
       return (
+        // @ts-ignore
         <ReactJson
           displayObjectSize={false}
           displayDataTypes={false}

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

@@ -32,6 +32,80 @@ const FileComponent = (props: Props) => {
   const isHttps = document.location.protocol === 'https:';
   const [temp, setTemp] = useState<boolean>(false);
 
+  const renderFile = () => {
+    if (['.jpg', '.png', '.swf', '.tiff'].some((item) => value?.formatValue.includes(item))) {
+      // 图片
+      return (
+        <div
+          className={props.type === 'card' ? styles.cardValue : styles.otherValue}
+          onClick={() => {
+            if (isHttps && value?.formatValue.indexOf('http:') !== -1) {
+              message.error('域名为https时,不支持访问http地址');
+            } else if (temp) {
+              message.error('该图片无法访问');
+            } else {
+              const flag =
+                ['.jpg', '.png'].find((item) => value?.formatValue.includes(item)) || '--';
+              setType(flag);
+              setVisible(true);
+            }
+          }}
+        >
+          <img
+            src={value?.formatValue}
+            onError={(e: any) => {
+              e.target.src = imgMap.get('error');
+              setTemp(true);
+            }}
+          />
+        </div>
+      );
+    }
+    if (
+      ['.m3u8', '.flv', '.mp4', '.rmvb', '.mvb'].some((item) => value?.formatValue.includes(item))
+    ) {
+      return (
+        <div
+          className={props.type === 'card' ? styles.cardValue : styles.otherValue}
+          onClick={() => {
+            if (isHttps && value?.formatValue.indexOf('http:') !== -1) {
+              message.error('域名为https时,不支持访问http地址');
+            } else if (['.rmvb', '.mvb'].some((item) => value?.formatValue.includes(item))) {
+              message.error('当前仅支持播放.mp4,.flv,.m3u8格式的视频');
+            } else {
+              const flag =
+                ['.m3u8', '.flv', '.mp4'].find((item) => value?.formatValue.includes(item)) || '--';
+              setType(flag);
+              setVisible(true);
+            }
+          }}
+        >
+          <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),
+        ) || '--';
+      return (
+        <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>
+          <img src={imgMap.get(flag.slice(1))} />
+        </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 (
@@ -42,85 +116,22 @@ const FileComponent = (props: Props) => {
         data?.valueType?.fileType === 'base64' ||
         data?.valueType?.fileType === 'Binary(二进制)'
       ) {
+        // if(data?.valueType?.fileType === 'base64') {
+        //   console.log(value?.formatValue.split(',')[0])
+        // }
+        // if(data?.valueType?.fileType === 'Binary(二进制)') {
+        //
+        // }
         return (
           <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>
             <Tooltip placement="topLeft" title={String(value?.formatValue)}>
               {String(value?.formatValue)}
             </Tooltip>
-          </div>
-        );
-      }
-      if (['.jpg', '.png', '.swf', '.tiff'].some((item) => value?.formatValue.includes(item))) {
-        // 图片
-        return (
-          <div
-            className={props.type === 'card' ? styles.cardValue : styles.otherValue}
-            onClick={() => {
-              if (isHttps && value?.formatValue.indexOf('http:') !== -1) {
-                message.error('域名为https时,不支持访问http地址');
-              } else if (temp) {
-                message.error('该图片无法访问');
-              } else {
-                const flag =
-                  ['.jpg', '.png'].find((item) => value?.formatValue.includes(item)) || '--';
-                setType(flag);
-                setVisible(true);
-              }
-            }}
-          >
-            <img
-              src={value?.formatValue}
-              onError={(e: any) => {
-                e.target.src = imgMap.get('error');
-                setTemp(true);
-              }}
-            />
-          </div>
-        );
-      }
-      if (
-        ['.m3u8', '.flv', '.mp4', '.rmvb', '.mvb'].some((item) => value?.formatValue.includes(item))
-      ) {
-        return (
-          <div
-            className={props.type === 'card' ? styles.cardValue : styles.otherValue}
-            onClick={() => {
-              if (isHttps && value?.formatValue.indexOf('http:') !== -1) {
-                message.error('域名为https时,不支持访问http地址');
-              } else if (['.rmvb', '.mvb'].some((item) => value?.formatValue.includes(item))) {
-                message.error('当前仅支持播放.mp4,.flv,.m3u8格式的视频');
-              } else {
-                const flag =
-                  ['.m3u8', '.flv', '.mp4'].find((item) => value?.formatValue.includes(item)) ||
-                  '--';
-                setType(flag);
-                setVisible(true);
-              }
-            }}
-          >
-            <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),
-          ) || '--';
-        return (
-          <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>
-            <img src={imgMap.get(flag.slice(1))} />
+            {/*<img src={value?.formatValue} />*/}
           </div>
         );
       } else {
-        return (
-          <div className={props.type === 'card' ? styles.cardValue : styles.otherValue}>
-            <img src={imgMap.get('other')} />
-          </div>
-        );
+        return renderFile();
       }
     } else if (data?.valueType?.type === 'object') {
       return (

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

@@ -36,7 +36,7 @@ const AccessConfig = (props: Props) => {
     terms: [],
   });
 
-  const [currrent, setCurrrent] = useState<any>({
+  const [current, setCurrent] = useState<any>({
     id: productModel.current?.accessId,
     name: productModel.current?.accessName,
     protocol: productModel.current?.messageProtocol,
@@ -84,7 +84,7 @@ const AccessConfig = (props: Props) => {
     };
     service.queryList({ ...temp, sorts: [{ name: 'createTime', order: 'desc' }] }).then((resp) => {
       setDataSource(resp?.result);
-      setCurrrent(resp?.result?.data?.[0]);
+      setCurrent(resp?.result?.data?.[0]);
     });
   };
 
@@ -151,15 +151,15 @@ const AccessConfig = (props: Props) => {
       width={1200}
       title={'设备接入配置'}
       onOk={async () => {
-        if (!!currrent) {
+        if (!!current) {
           const obj: any = {
             ...productModel.current,
-            transportProtocol: currrent.transport,
-            protocolName: currrent.protocolDetail.name,
-            accessId: currrent.id,
-            accessName: currrent.name,
-            accessProvider: currrent.provider,
-            messageProtocol: currrent.protocol,
+            transportProtocol: current?.transport,
+            protocolName: current?.protocolDetail?.name,
+            accessId: current.id,
+            accessName: current.name,
+            accessProvider: current.provider,
+            messageProtocol: current.protocol,
           };
           const metatdata = JSON.parse(productModel.current?.metadata || '{}');
           if (!productModel.current?.metadata) {
@@ -233,13 +233,14 @@ const AccessConfig = (props: Props) => {
               key={item.id}
               span={12}
               onClick={() => {
-                setCurrrent(item);
+                setCurrent(item);
               }}
             >
               <AccessConfigCard
                 {...item}
+                showMask={false}
                 showTool={false}
-                activeStyle={currrent?.id === item.id ? 'active' : ''}
+                activeStyle={current?.id === item.id ? 'active' : ''}
               />
             </Col>
           ))}

+ 1 - 1
src/pages/device/Product/Detail/BaseInfo/index.tsx

@@ -157,7 +157,7 @@ const BaseInfo = (props: BaseInfoProps) => {
         size="small"
         column={3}
         title={[
-          <span key={1}>产品信息</span>,
+          <span key={1}>配置信息</span>,
           <PermissionButton
             isPermission={permission.update}
             key={2}

+ 13 - 5
src/pages/device/components/Metadata/Cat/index.tsx

@@ -1,12 +1,12 @@
 import { Button, Drawer, message, Space, Tabs } from 'antd';
 import { useEffect, useState } from 'react';
 import { productModel, service } from '@/pages/device/Product';
-import MonacoEditor from 'react-monaco-editor';
 import { observer } from '@formily/react';
 import { InstanceModel } from '@/pages/device/Instance';
 import { useLocation } from 'umi';
 import InstanceService from '@/pages/device/Instance/service';
 import { downloadObject } from '@/utils/util';
+import { JMonacoEditor } from '@/components/FMonacoEditor';
 
 interface Props {
   visible: boolean;
@@ -71,9 +71,17 @@ const Cat = observer((props: Props) => {
             type="primary"
             onClick={async () => {
               try {
-                downloadObject(JSON.parse(value), `设备-物模型`, 'YYYY/MM/DD');
+                downloadObject(
+                  JSON.parse(value),
+                  `${
+                    props.type === 'device'
+                      ? InstanceModel.current?.name
+                      : productModel.current?.name
+                  }-物模型`,
+                  'YYYY/MM/DD',
+                );
               } catch (e) {
-                message.error('物模型格式错误!');
+                message.error('请先配置物模型');
               }
             }}
           >
@@ -93,13 +101,13 @@ const Cat = observer((props: Props) => {
         {codecs?.map((item) => (
           <Tabs.TabPane tab={item.name} tabKey={item.id} key={item.id}>
             <div style={{ border: '1px solid #eee', height: 670, width: 650 }}>
-              <MonacoEditor
+              <JMonacoEditor
                 height={'100%'}
                 theme="vs"
                 language="json"
                 key={item.id}
                 value={value}
-                editorDidMount={(editor) => {
+                editorDidMount={(editor: any) => {
                   editor.getAction('editor.action.formatDocument').run();
                   editor.onDidScrollChange?.(() => {
                     editor.getAction('editor.action.formatDocument').run();

+ 33 - 30
src/pages/device/components/Metadata/Import/index.tsx

@@ -298,43 +298,46 @@ const Import = (props: Props) => {
           onlyMessage('发生错误!', 'error');
         },
       });
+      Store.set(SystemConst.GET_METADATA, true);
+      Store.set(SystemConst.REFRESH_METADATA_TABLE, true);
+      props.close();
     } else {
-      const params = {
-        id: param.id,
-        metadata: JSON.stringify(
+      try {
+        const params = {
+          id: param.id,
+          metadata: JSON.stringify(
+            operateLimits(
+              JSON.parse(data[props?.type === 'device' ? 'import' : data?.type] || '{}'),
+            ),
+          ),
+        };
+        const paramsDevice = JSON.stringify(
           operateLimits(JSON.parse(data[props?.type === 'device' ? 'import' : data?.type] || '{}')),
-        ),
-      };
-      // const paramsDevice = {
-      //   id: param.id,
-      //   deriveMetadata: JSON.stringify(
-      //     operateLimits(JSON.parse(data[props?.type === 'device' ? 'import' : data?.type] || '{}')),
-      //   ),
-      // };
-      const paramsDevice = JSON.stringify(
-        operateLimits(JSON.parse(data[props?.type === 'device' ? 'import' : data?.type] || '{}')),
-      );
-      let resp: any = undefined;
-      if (props?.type === 'device') {
-        resp = await deviceService.saveMetadata(param.id, paramsDevice);
-      } else {
-        resp = await service.modify(param.id, params);
-      }
-      if (resp.status === 200) {
+        );
+        let resp: any = undefined;
         if (props?.type === 'device') {
-          const metadata: DeviceMetadata = JSON.parse(paramsDevice || '{}');
-          MetadataAction.insert(metadata);
-          onlyMessage('导入成功');
+          resp = await deviceService.saveMetadata(param.id, paramsDevice);
         } else {
-          const metadata: DeviceMetadata = JSON.parse(params?.metadata || '{}');
-          MetadataAction.insert(metadata);
-          onlyMessage('导入成功');
+          resp = await service.modify(param.id, params);
+        }
+        if (resp.status === 200) {
+          if (props?.type === 'device') {
+            const metadata: DeviceMetadata = JSON.parse(paramsDevice || '{}');
+            MetadataAction.insert(metadata);
+            onlyMessage('导入成功');
+          } else {
+            const metadata: DeviceMetadata = JSON.parse(params?.metadata || '{}');
+            MetadataAction.insert(metadata);
+            onlyMessage('导入成功');
+          }
         }
+        Store.set(SystemConst.GET_METADATA, true);
+        Store.set(SystemConst.REFRESH_METADATA_TABLE, true);
+        props.close();
+      } catch (err) {
+        onlyMessage('请上传正确的json格式文件', 'error');
       }
     }
-    Store.set(SystemConst.GET_METADATA, true);
-    Store.set(SystemConst.REFRESH_METADATA_TABLE, true);
-    props.close();
   };
   return (
     <Modal

+ 1 - 0
src/pages/link/AccessConfig/index.tsx

@@ -129,6 +129,7 @@ const AccessConfig = () => {
                   <Col key={item.id} span={12}>
                     <AccessConfigCard
                       {...item}
+                      showMask={true}
                       detail={
                         <PermissionButton
                           key={'view'}

+ 12 - 6
src/pages/link/DashBoard/index.tsx

@@ -250,8 +250,10 @@ export default () => {
         type: 'value',
       },
       grid: {
-        left: '50px',
-        right: '50px',
+        left: 50,
+        right: 0,
+        top: 10,
+        bottom: 10,
       },
       color: ['#979AFF'],
       series: Object.keys(data).length
@@ -297,8 +299,10 @@ export default () => {
         type: 'value',
       },
       grid: {
-        left: '50px',
-        right: '30px',
+        left: 30,
+        right: 0,
+        top: 10,
+        bottom: 10,
       },
       dataZoom: [
         {
@@ -356,8 +360,10 @@ export default () => {
         type: 'value',
       },
       grid: {
-        left: '50px',
-        right: '30px',
+        left: 30,
+        right: 0,
+        top: 10,
+        bottom: 10,
       },
       dataZoom: [
         {

+ 2 - 2
src/pages/link/DataCollect/Dashboard/index.tsx

@@ -165,8 +165,8 @@ const DeviceBoard = () => {
         grid: {
           top: '2%',
           bottom: '5%',
-          // left: '50px',
-          // right: '50px',
+          left: '65px',
+          right: 0,
         },
         series: [
           {

+ 24 - 1
src/pages/link/DataCollect/components/Channel/index.tsx

@@ -20,9 +20,11 @@ interface Props {
 const ChannelModel = model<{
   visible: boolean;
   current: Partial<ChannelItem>;
+  currentPage: number;
 }>({
   visible: false,
   current: {},
+  currentPage: 0,
 });
 
 export default observer((props: Props) => {
@@ -133,6 +135,24 @@ export default observer((props: Props) => {
       return {};
     }
   };
+
+  const onPageChange = (page: number, size: number) => {
+    if (ChannelModel.currentPage === size) {
+      handleSearch({
+        ...param,
+        pageIndex: page - 1,
+        pageSize: size,
+      });
+    } else {
+      ChannelModel.currentPage = size;
+      handleSearch({
+        ...param,
+        pageIndex: 0,
+        pageSize: size,
+      });
+    }
+  };
+
   return (
     <div>
       <SearchComponent<ChannelItem>
@@ -279,9 +299,12 @@ export default observer((props: Props) => {
               total={dataSource?.total || 0}
               current={dataSource?.pageIndex + 1}
               onChange={(page, size) => {
+                onPageChange(page, size);
+              }}
+              onShowSizeChange={(current, size) => {
                 handleSearch({
                   ...param,
-                  pageIndex: page - 1,
+                  pageIndex: 1,
                   pageSize: size,
                 });
               }}

+ 20 - 5
src/pages/link/DataCollect/components/Device/index.tsx

@@ -30,9 +30,11 @@ interface Props {
 const CollectorModel = model<{
   visible: boolean;
   current: Partial<CollectorItem>;
+  currentPage: number;
 }>({
   visible: false,
   current: {},
+  currentPage: 0,
 });
 
 export default observer((props: Props) => {
@@ -201,6 +203,23 @@ export default observer((props: Props) => {
     }
   };
 
+  const onPageChange = (page: number, size: number) => {
+    if (CollectorModel.currentPage === size) {
+      handleSearch({
+        ...param,
+        pageIndex: page - 1,
+        pageSize: size,
+      });
+    } else {
+      CollectorModel.currentPage = size;
+      handleSearch({
+        ...param,
+        pageIndex: 0,
+        pageSize: size,
+      });
+    }
+  };
+
   return (
     <div>
       <SearchComponent<CollectorItem>
@@ -373,11 +392,7 @@ export default observer((props: Props) => {
                     total={dataSource?.total || 0}
                     current={dataSource?.pageIndex + 1}
                     onChange={(page, size) => {
-                      handleSearch({
-                        ...param,
-                        pageIndex: page - 1,
-                        pageSize: size,
-                      });
+                      onPageChange(page, size);
                     }}
                     pageSizeOptions={[12, 24, 48, 96]}
                     pageSize={dataSource?.pageSize}

+ 20 - 5
src/pages/link/DataCollect/components/Point/index.tsx

@@ -43,6 +43,7 @@ const PointModel = model<{
   selectKey: string[];
   arr: any[];
   checkAll: boolean;
+  currentPage: number;
 }>({
   m_visible: false,
   p_visible: false,
@@ -55,6 +56,7 @@ const PointModel = model<{
   selectKey: [],
   arr: [],
   checkAll: false,
+  currentPage: 0,
 });
 
 const PointCard = observer((props: PointCardProps) => {
@@ -142,6 +144,23 @@ const PointCard = observer((props: PointCardProps) => {
     };
   }, []);
 
+  const onPageChange = (page: number, size: number) => {
+    if (PointModel.currentPage === size) {
+      handleSearch({
+        ...param,
+        pageIndex: page - 1,
+        pageSize: size,
+      });
+    } else {
+      PointModel.currentPage = size;
+      handleSearch({
+        ...param,
+        pageIndex: 0,
+        pageSize: size,
+      });
+    }
+  };
+
   const menu = (
     <Menu>
       <Menu.Item key="1">
@@ -333,11 +352,7 @@ const PointCard = observer((props: PointCardProps) => {
                     total={dataSource?.total || 0}
                     current={dataSource?.pageIndex + 1}
                     onChange={(page, size) => {
-                      handleSearch({
-                        ...param,
-                        pageIndex: page - 1,
-                        pageSize: size,
-                      });
+                      onPageChange(page, size);
                     }}
                     pageSizeOptions={[12, 24, 48, 96]}
                     pageSize={dataSource?.pageSize}

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

@@ -86,8 +86,8 @@ export default (props: BuiltInProps) => {
     } else {
       const type = props.data?.type;
       if (type === 'date') {
-        // @ts-ignore
         return (
+          // @ts-ignore
           <DatePicker
             value={value ? moment(value, 'YYYY-MM-DD HH:mm:ss') : undefined}
             style={{ width: '100%' }}

+ 12 - 5
src/pages/rule-engine/Scene/Save/action/notify/index.tsx

@@ -95,11 +95,18 @@ export default observer((props: Props) => {
     if (NotifyModel.current === 0) {
       const val = await WayRef.current?.save();
       if (val) {
-        NotifyModel.notify = {
-          notifyType: val,
-          notifierId: '',
-          templateId: '',
-        };
+        if (val !== NotifyModel.notify.notifyType) {
+          NotifyModel.notify = {
+            notifyType: val,
+            notifierId: '',
+            templateId: '',
+          };
+        } else {
+          NotifyModel.notify = {
+            ...NotifyModel.notify,
+            notifyType: val,
+          };
+        }
         NotifyModel.variable = [];
         NotifyModel.current += 1;
       }

+ 11 - 5
src/pages/rule-engine/Scene/index.tsx

@@ -68,11 +68,11 @@ const Scene = () => {
           style={{ padding: 0 }}
           isPermission={permission.tigger}
           tooltip={{
-            title: record.state?.value === 'disabled' ? '未启用,不能手动触发' : '',
+            title: record.state?.value === 'disable' ? '未启用,不能手动触发' : '',
           }}
-          disabled={record.state?.value === 'disabled'}
+          disabled={record.state?.value === 'disable'}
           popConfirm={{
-            disabled: record.state?.value === 'disabled',
+            disabled: record.state?.value === 'disable',
             title: '确认手动触发?',
             onConfirm: async () => {
               await service._execute(record.id);
@@ -95,10 +95,16 @@ const Scene = () => {
         type={'link'}
         style={{ padding: 0 }}
         isPermission={permission.action}
+        disabled={!(!!record?.triggerType && (record?.branches || [])?.length)}
+        tooltip={{
+          title: !(!!record.triggerType && (record.branches || [])?.length)
+            ? '未配置规则的不能启用'
+            : '',
+        }}
         popConfirm={{
           title: intl.formatMessage({
             id: `pages.data.option.${
-              record.state.value === 'started' ? 'disabled' : 'enabled'
+              record.state.value === 'started' ? 'disable' : 'enabled'
             }.tips`,
             defaultMessage: '确认禁用?',
           }),
@@ -131,7 +137,7 @@ const Scene = () => {
       >
         {record.state.value === 'started' ? <StopOutlined /> : <PlayCircleOutlined />}
         {intl.formatMessage({
-          id: `pages.data.option.${record.state.value === 'started' ? 'disabled' : 'enabled'}`,
+          id: `pages.data.option.${record.state.value === 'started' ? 'disable' : 'enabled'}`,
           defaultMessage: record.state.value === 'started' ? '禁用' : '启用',
         })}
       </PermissionButton>,