Parcourir la source

fix: 修复bug

sun-chaochao il y a 3 ans
Parent
commit
909eaf6469

+ 43 - 0
src/pages/device/Instance/Detail/Diagnose/Status/DiagnosticAdvice.tsx

@@ -0,0 +1,43 @@
+import { randomString } from '@/utils/util';
+import { InfoCircleOutlined } from '@ant-design/icons';
+import { Modal } from 'antd';
+import styles from './index.less';
+
+interface Props {
+  close: () => void;
+  data: any[];
+}
+
+const DiagnosticAdvice = (props: Props) => {
+  const { data } = props;
+
+  return (
+    <Modal
+      title="诊断建议"
+      onCancel={() => {
+        props.close();
+      }}
+      onOk={() => {
+        props.close();
+      }}
+      width={700}
+      visible
+    >
+      <div className={styles.advice}>
+        <div className={styles.alert}>
+          <InfoCircleOutlined style={{ marginRight: 10 }} />
+          所有诊断均无异常但设备任未上线,请检查以下内容
+        </div>
+        <div>
+          {(data || []).map((item: any) => (
+            <div className={styles.infoItem} key={randomString()} style={{ margin: '10px 0' }}>
+              {item}
+            </div>
+          ))}
+        </div>
+      </div>
+    </Modal>
+  );
+};
+
+export default DiagnosticAdvice;

+ 4 - 2
src/pages/device/Instance/Detail/Diagnose/Status/ManualInspection.tsx

@@ -25,7 +25,7 @@ const ManualInspection = (props: Props) => {
       onCancel={() => {
       onCancel={() => {
         props.close();
         props.close();
       }}
       }}
-      width={800}
+      width={900}
       footer={[
       footer={[
         <Button
         <Button
           key="back"
           key="back"
@@ -83,7 +83,9 @@ const ManualInspection = (props: Props) => {
           </div>
           </div>
         </div>
         </div>
         {data?.data?.description ? (
         {data?.data?.description ? (
-          <div style={{ width: '50%', border: '1px solid #f0f0f0' }}>
+          <div
+            style={{ width: '50%', border: '1px solid #f0f0f0', padding: 10, borderLeft: 'none' }}
+          >
             <h4>诊断项说明</h4>
             <h4>诊断项说明</h4>
             <p>{data?.data?.description}</p>
             <p>{data?.data?.description}</p>
           </div>
           </div>

+ 178 - 132
src/pages/device/Instance/Detail/Diagnose/Status/index.tsx

@@ -20,13 +20,14 @@ import { useState } from 'react';
 import { useEffect } from 'react';
 import { useEffect } from 'react';
 import { InstanceModel, service } from '@/pages/device/Instance';
 import { InstanceModel, service } from '@/pages/device/Instance';
 import _ from 'lodash';
 import _ from 'lodash';
-import { onlyMessage, randomString } from '@/utils/util';
+import { onlyMessage } from '@/utils/util';
 import { getMenuPathByCode, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { getMenuPathByCode, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 // import PermissionButton from '@/components/PermissionButton';
 // import PermissionButton from '@/components/PermissionButton';
 import ManualInspection from './ManualInspection';
 import ManualInspection from './ManualInspection';
 import useHistory from '@/hooks/route/useHistory';
 import useHistory from '@/hooks/route/useHistory';
+import DiagnosticAdvice from './DiagnosticAdvice';
 interface Props {
 interface Props {
-  providerType: 'network' | 'child-device' | 'media' | 'cloud' | 'channel';
+  providerType: 'network' | 'child-device' | 'media' | 'cloud' | 'channel' | undefined;
 }
 }
 
 
 const Status = observer((props: Props) => {
 const Status = observer((props: Props) => {
@@ -42,6 +43,8 @@ const Status = observer((props: Props) => {
 
 
   const [artificialVisible, setArtificialVisible] = useState<boolean>(false);
   const [artificialVisible, setArtificialVisible] = useState<boolean>(false);
   const [artificiaData, setArtificiaData] = useState<any>({});
   const [artificiaData, setArtificiaData] = useState<any>({});
+  const [diagnoseVisible, setDiagnoseVisible] = useState<boolean>(false);
+  const [diagnoseData, setDiagnoseData] = useState<any>({});
 
 
   // 跳转到产品设备接入配置
   // 跳转到产品设备接入配置
   const jumpAccessConfig = () => {
   const jumpAccessConfig = () => {
@@ -368,7 +371,7 @@ const Status = observer((props: Props) => {
 
 
   // 网关父设备
   // 网关父设备
   const diagnoseParentDevice = () =>
   const diagnoseParentDevice = () =>
-    new Promise((resolve) => {
+    new Promise(async (resolve) => {
       DiagnoseStatusModel.count++;
       DiagnoseStatusModel.count++;
       if (device.state?.value === 'online') {
       if (device.state?.value === 'online') {
         setTimeout(() => {
         setTimeout(() => {
@@ -411,6 +414,67 @@ const Status = observer((props: Props) => {
             resolve({});
             resolve({});
           }, time);
           }, time);
         } else {
         } else {
+          let item: ListProps | undefined = undefined;
+          const response = await service.detail(device?.parentId);
+          if (response.status === 200) {
+            if (response?.state?.value === 'notActive') {
+              item = {
+                key: 'parent-device',
+                name: '网关父设备',
+                desc: '诊断网关父设备状态是否正常,禁用或离线将导致连接失败',
+                status: 'error',
+                text: '异常',
+                info: (
+                  <div>
+                    <div className={styles.infoItem}>
+                      <Badge
+                        status="default"
+                        text={
+                          <span>
+                            网关父设备已禁用,请先<a>启用</a>
+                          </span>
+                        }
+                      />
+                    </div>
+                  </div>
+                ),
+              };
+            } else if (response?.state?.value === 'online') {
+              item = {
+                key: 'parent-device',
+                name: '网关父设备',
+                desc: '诊断网关父设备状态是否正常,禁用或离线将导致连接失败',
+                status: 'success',
+                text: '正常',
+                info: null,
+              };
+            } else {
+              item = {
+                key: 'parent-device',
+                name: '网关父设备',
+                desc: '诊断网关父设备状态是否正常,禁用或离线将导致连接失败',
+                status: 'error',
+                text: '异常',
+                info: (
+                  <div>
+                    <div className={styles.infoItem}>
+                      <Badge
+                        status="default"
+                        text={<span>网关父设备已离线,请先排查网关设备故障</span>}
+                      />
+                    </div>
+                  </div>
+                ),
+              };
+            }
+            setTimeout(() => {
+              if (item) {
+                DiagnoseStatusModel.list = modifyArrayList(DiagnoseStatusModel.list, item);
+                DiagnoseStatusModel.count++;
+              }
+              resolve({});
+            }, time);
+          }
         }
         }
       }
       }
       setTimeout(() => {
       setTimeout(() => {
@@ -546,6 +610,7 @@ const Status = observer((props: Props) => {
                           onConfirm={async () => {
                           onConfirm={async () => {
                             const resp = await service.deployDevice(device?.id || '');
                             const resp = await service.deployDevice(device?.id || '');
                             if (resp.status === 200) {
                             if (resp.status === 200) {
+                              InstanceModel.detail.state = { value: 'offline', text: '离线' };
                               onlyMessage('操作成功!');
                               onlyMessage('操作成功!');
                               DiagnoseStatusModel.list = modifyArrayList(DiagnoseStatusModel.list, {
                               DiagnoseStatusModel.list = modifyArrayList(DiagnoseStatusModel.list, {
                                 key: 'device',
                                 key: 'device',
@@ -1033,146 +1098,119 @@ const Status = observer((props: Props) => {
   // })
   // })
 
 
   // 设备离线且全部诊断项都是正确的情况后
   // 设备离线且全部诊断项都是正确的情况后
-  const diagnoseNetworkOtherConfig = () =>
-    new Promise(async (resolve) => {
-      if (device.state?.value != 'online') {
-        const item: ReactNode[] = [];
-        if (providerType === 'network') {
-          DiagnoseStatusModel.configuration.product.map((it) => {
-            item.push(
-              <Badge
-                status="default"
-                text={
-                  <span>
-                    产品-{it.name}规则可能有加密处理,请认真查看
-                    <a
-                      onClick={() => {
-                        jumpAccessConfig();
-                      }}
-                    >
-                      设备接入配置
-                    </a>
-                    中【消息协议】说明
-                  </span>
-                }
-              />,
-            );
-          });
-          DiagnoseStatusModel.configuration.device.map((it) => {
-            item.push(
-              <Badge
-                status="default"
-                text={
-                  <span>
-                    设备-{it.name}规则可能有加密处理,请认真查看
-                    <a
-                      onClick={() => {
-                        jumpAccessConfig();
-                      }}
-                    >
-                      设备接入配置
-                    </a>
-                    中【消息协议】说明
-                  </span>
-                }
-              />,
-            );
-          });
-          if (
-            device?.protocol &&
-            device?.accessProvider &&
-            gatewayList.includes(device?.accessProvider)
-          ) {
-            const response = await service.queryProcotolDetail(device.protocol, 'MQTT');
-            if (response.status === 200) {
-              if ((response.result?.routes || []).length > 0) {
-                item.push(
-                  <Badge
-                    status="default"
-                    text={
-                      // accessPermission.view ? (
-                      <span>
-                        请根据
-                        <a
-                          onClick={() => {
-                            jumpAccessConfig();
-                          }}
-                        >
-                          设备接入配置
-                        </a>
-                        中${urlMap.get(device?.accessProvider) || ''}信息,任意上报一条数据
-                      </span>
-                      // ) : (
-                      //   `请联系管理员提供${
-                      //     urlMap.get(device?.accessProvider) || ''
-                      //   }信息,并根据URL信息任意上报一条数据)`
-                      // )
-                    }
-                  />,
-                );
-              } else {
-                item.push(
-                  <Badge
-                    status="default"
-                    text={
-                      <span>
-                        请联系管理员提供${urlMap.get(device?.accessProvider) || ''}
-                        信息,并根据URL信息任意上报一条数据
-                      </span>
-                    }
-                  />,
-                );
+  const diagnoseNetworkOtherConfig = async () => {
+    if (device.state?.value != 'online') {
+      const item: ReactNode[] = [];
+      if (providerType === 'network') {
+        DiagnoseStatusModel.configuration.product.map((it) => {
+          item.push(
+            <Badge
+              status="default"
+              text={
+                <span>
+                  产品-{it.name}规则可能有加密处理,请认真查看
+                  <a
+                    onClick={() => {
+                      jumpAccessConfig();
+                    }}
+                  >
+                    设备接入配置
+                  </a>
+                  中【消息协议】说明
+                </span>
+              }
+            />,
+          );
+        });
+        DiagnoseStatusModel.configuration.device.map((it) => {
+          item.push(
+            <Badge
+              status="default"
+              text={
+                <span>
+                  设备-{it.name}规则可能有加密处理,请认真查看
+                  <a
+                    onClick={() => {
+                      jumpAccessConfig();
+                    }}
+                  >
+                    设备接入配置
+                  </a>
+                  中【消息协议】说明
+                </span>
               }
               }
+            />,
+          );
+        });
+        if (
+          device?.protocol &&
+          device?.accessProvider &&
+          gatewayList.includes(device?.accessProvider)
+        ) {
+          const response = await service.queryProcotolDetail(device.protocol, 'MQTT');
+          if (response.status === 200) {
+            if ((response.result?.routes || []).length > 0) {
+              item.push(
+                <Badge
+                  status="default"
+                  text={
+                    // accessPermission.view ? (
+                    <span>
+                      请根据
+                      <a
+                        onClick={() => {
+                          jumpAccessConfig();
+                        }}
+                      >
+                        设备接入配置
+                      </a>
+                      中${urlMap.get(device?.accessProvider) || ''}信息,任意上报一条数据
+                    </span>
+                    // ) : (
+                    //   `请联系管理员提供${
+                    //     urlMap.get(device?.accessProvider) || ''
+                    //   }信息,并根据URL信息任意上报一条数据)`
+                    // )
+                  }
+                />,
+              );
+            } else {
+              item.push(
+                <Badge
+                  status="default"
+                  text={
+                    <span>
+                      请联系管理员提供${urlMap.get(device?.accessProvider) || ''}
+                      信息,并根据URL信息任意上报一条数据
+                    </span>
+                  }
+                />,
+              );
             }
             }
           }
           }
-        } else if (providerType === 'child-device') {
-        } else if (providerType === 'media') {
-        } else if (providerType === 'cloud') {
-        } else if (providerType === 'channel') {
         }
         }
-        item.push(<Badge status="default" text="请检查设备是否已开机" />);
-        setTimeout(() => {
-          DiagnoseStatusModel.list = modifyArrayList(
-            DiagnoseStatusModel.list,
-            {
-              key: 'other',
-              name: '其他可能异常',
-              desc: '当以上诊断均无异常时,请检查以下内容',
-              status: 'error',
-              text: '可能存在异常',
-              info: (
-                <div>
-                  {item.map((i) => (
-                    <div key={randomString()} className={styles.infoItem}>
-                      {i}
-                    </div>
-                  ))}
-                </div>
-              ),
-            },
-            DiagnoseStatusModel.list.length,
-          );
-          DiagnoseStatusModel.count++;
-          DiagnoseStatusModel.percent = 100;
-          resolve({});
-        }, time);
-      } else {
-        DiagnoseStatusModel.state = 'success';
+      } else if (providerType === 'child-device') {
+      } else if (providerType === 'media') {
+      } else if (providerType === 'cloud') {
+      } else if (providerType === 'channel') {
       }
       }
-    });
+      item.push(<Badge status="default" text="请检查设备是否已开机" />);
+      setDiagnoseData(item);
+      setDiagnoseVisible(true);
+    } else {
+      DiagnoseStatusModel.state = 'success';
+    }
+  };
 
 
   useEffect(() => {
   useEffect(() => {
     if (DiagnoseStatusModel.status === 'finish') {
     if (DiagnoseStatusModel.status === 'finish') {
       const list = _.uniq(_.map(DiagnoseStatusModel.list, 'status'));
       const list = _.uniq(_.map(DiagnoseStatusModel.list, 'status'));
       if (device.state?.value !== 'online') {
       if (device.state?.value !== 'online') {
+        DiagnoseStatusModel.state = 'error';
         if (list[0] === 'success' && list.length === 1) {
         if (list[0] === 'success' && list.length === 1) {
           diagnoseNetworkOtherConfig();
           diagnoseNetworkOtherConfig();
-        } else if (list.includes('error')) {
-          DiagnoseStatusModel.percent = 100;
-          DiagnoseStatusModel.state = 'error';
         }
         }
       } else {
       } else {
-        DiagnoseStatusModel.percent = 100;
         DiagnoseStatusModel.state = 'success';
         DiagnoseStatusModel.state = 'success';
       }
       }
     }
     }
@@ -1226,15 +1264,15 @@ const Status = observer((props: Props) => {
       await diagnoseProduct();
       await diagnoseProduct();
       await diagnoseDevice();
       await diagnoseDevice();
     }
     }
-    DiagnoseStatusModel.percent = 90;
+    DiagnoseStatusModel.percent = 100;
     DiagnoseStatusModel.status = 'finish';
     DiagnoseStatusModel.status = 'finish';
   };
   };
 
 
   useEffect(() => {
   useEffect(() => {
-    if (DiagnoseStatusModel.state === 'loading') {
+    if (DiagnoseStatusModel.state === 'loading' && providerType) {
       handleSearch();
       handleSearch();
     }
     }
-  }, [DiagnoseStatusModel.state]);
+  }, [DiagnoseStatusModel.state, providerType]);
 
 
   return (
   return (
     <div className={styles.statusBox}>
     <div className={styles.statusBox}>
@@ -1274,6 +1312,14 @@ const Status = observer((props: Props) => {
           </div>
           </div>
         ))}
         ))}
       </div>
       </div>
+      {diagnoseVisible && (
+        <DiagnosticAdvice
+          data={diagnoseData}
+          close={() => {
+            setDiagnoseVisible(false);
+          }}
+        />
+      )}
       {artificialVisible && (
       {artificialVisible && (
         <ManualInspection
         <ManualInspection
           data={artificiaData}
           data={artificiaData}

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

@@ -21,8 +21,8 @@ const Diagnose = observer(() => {
   const { minHeight } = useDomFullHeight(`.diagnose`, 12);
   const { minHeight } = useDomFullHeight(`.diagnose`, 12);
   const [current, setCurrent] = useState<string>('status');
   const [current, setCurrent] = useState<string>('status');
   const [providerType, setProviderType] = useState<
   const [providerType, setProviderType] = useState<
-    'network' | 'child-device' | 'media' | 'cloud' | 'channel'
-  >('network');
+    undefined | 'network' | 'child-device' | 'media' | 'cloud' | 'channel'
+  >(undefined);
 
 
   const ViewMap = {
   const ViewMap = {
     status: <Status providerType={providerType} />,
     status: <Status providerType={providerType} />,

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

@@ -91,6 +91,19 @@ const AccessConfig = (props: Props) => {
       dataIndex: 'name',
       dataIndex: 'name',
     },
     },
     {
     {
+      title: '网关类型',
+      dataIndex: 'provider',
+      renderText: (text) => text?.text,
+      valueType: 'select',
+      request: () =>
+        service.getProviders().then((resp: any) => {
+          return (resp?.result || []).map((item: any) => ({
+            label: item.name,
+            value: item.id,
+          }));
+        }),
+    },
+    {
       title: '状态',
       title: '状态',
       dataIndex: 'state',
       dataIndex: 'state',
       valueType: 'select',
       valueType: 'select',

+ 31 - 0
src/pages/device/components/Metadata/Base/Edit/index.tsx

@@ -693,6 +693,9 @@ const Edit = observer((props: Props) => {
             'x-component': 'ArrayItems',
             'x-component': 'ArrayItems',
             'x-decorator': 'FormItem',
             'x-decorator': 'FormItem',
             title: '指标配置',
             title: '指标配置',
+            'x-decorator-props': {
+              tooltip: '场景联动页面可引用指标配置作为触发条件',
+            },
             'x-visible': props.type === 'product',
             'x-visible': props.type === 'product',
             items: {
             items: {
               type: 'object',
               type: 'object',
@@ -761,6 +764,16 @@ const Edit = observer((props: Props) => {
                         labelAlign: 'left',
                         labelAlign: 'left',
                         layout: 'vertical',
                         layout: 'vertical',
                       },
                       },
+                      'x-validator': [
+                        {
+                          max: 64,
+                          message: '最多可输入64个字符',
+                        },
+                        {
+                          required: true,
+                          message: '请输入名称',
+                        },
+                      ],
                     },
                     },
                     space: {
                     space: {
                       type: 'void',
                       type: 'void',
@@ -771,6 +784,12 @@ const Edit = observer((props: Props) => {
                         labelAlign: 'left',
                         labelAlign: 'left',
                         layout: 'vertical',
                         layout: 'vertical',
                       },
                       },
+                      'x-validator': [
+                        {
+                          required: true,
+                          message: '请输入指标值',
+                        },
+                      ],
                       'x-component-props': {
                       'x-component-props': {
                         maxColumns: 12,
                         maxColumns: 12,
                         minColumns: 12,
                         minColumns: 12,
@@ -782,6 +801,12 @@ const Edit = observer((props: Props) => {
                           'x-decorator-props': {
                           'x-decorator-props': {
                             gridSpan: 5,
                             gridSpan: 5,
                           },
                           },
+                          'x-validator': [
+                            {
+                              required: true,
+                              message: '请输入',
+                            },
+                          ],
                           'x-reactions': {
                           'x-reactions': {
                             dependencies: ['..range', 'valueType.type'],
                             dependencies: ['..range', 'valueType.type'],
                             fulfill: {
                             fulfill: {
@@ -803,6 +828,12 @@ const Edit = observer((props: Props) => {
                           'x-decorator-props': {
                           'x-decorator-props': {
                             gridSpan: 5,
                             gridSpan: 5,
                           },
                           },
+                          'x-validator': [
+                            {
+                              required: true,
+                              message: '请输入',
+                            },
+                          ],
                           'x-reactions': [
                           'x-reactions': [
                             {
                             {
                               dependencies: ['..range', 'valueType.type'],
                               dependencies: ['..range', 'valueType.type'],

+ 1 - 1
src/pages/link/AccessConfig/Detail/Access/data.ts

@@ -11,7 +11,7 @@ const ProcotoleMapping = new Map();
 ProcotoleMapping.set('websocket-server', 'WebSocket');
 ProcotoleMapping.set('websocket-server', 'WebSocket');
 ProcotoleMapping.set('http-server-gateway', 'HTTP');
 ProcotoleMapping.set('http-server-gateway', 'HTTP');
 ProcotoleMapping.set('udp-device-gateway', 'UDP');
 ProcotoleMapping.set('udp-device-gateway', 'UDP');
-ProcotoleMapping.set('coap-server-gateway', 'COAP');
+ProcotoleMapping.set('coap-server-gateway', 'CoAP');
 ProcotoleMapping.set('mqtt-client-gateway', 'MQTT');
 ProcotoleMapping.set('mqtt-client-gateway', 'MQTT');
 ProcotoleMapping.set('mqtt-server-gateway', 'MQTT');
 ProcotoleMapping.set('mqtt-server-gateway', 'MQTT');
 ProcotoleMapping.set('tcp-server-gateway', 'TCP');
 ProcotoleMapping.set('tcp-server-gateway', 'TCP');

+ 1 - 1
src/pages/link/Type/Detail/index.tsx

@@ -506,7 +506,7 @@ const Save = observer(() => {
         'x-decorator-props': {
         'x-decorator-props': {
           gridSpan: 1,
           gridSpan: 1,
           labelAlign: 'left',
           labelAlign: 'left',
-          tooltip: '对外提供访问的地址,内网环境是填写服务器的内网IP地址',
+          tooltip: '单次收发消息的最大长度,单位:字节;设置过大可能会影响性能',
           layout: 'vertical',
           layout: 'vertical',
         },
         },
         'x-component-props': {
         'x-component-props': {