Kaynağa Gözat

fix: 修复一系列bug

hear 2 yıl önce
ebeveyn
işleme
0e04d0b6d2
34 değiştirilmiş dosya ile 434 ekleme ve 189 silme
  1. 2 2
      config/proxy.ts
  2. 5 2
      src/components/Player/ScreenPlayer.tsx
  3. 1 1
      src/components/SearchComponent/index.tsx
  4. 66 22
      src/pages/DataCollect/Channel/Save/index.tsx
  5. 1 1
      src/pages/DataCollect/Collector/components/Point/Save/modbus.tsx
  6. 10 4
      src/pages/DataCollect/Dashboard/index.tsx
  7. 4 0
      src/pages/DataCollect/service.ts
  8. 10 2
      src/pages/Log/Access/index.tsx
  9. 8 1
      src/pages/device/Instance/Detail/Tags/index.tsx
  10. 5 0
      src/pages/device/Instance/service.ts
  11. 32 10
      src/pages/device/Product/Detail/Access/index.tsx
  12. 45 0
      src/pages/edge/Device/Remote/index.tsx
  13. 21 11
      src/pages/edge/Device/index.tsx
  14. 1 1
      src/pages/edge/Resource/index.tsx
  15. 46 46
      src/pages/home/Api/index.tsx
  16. 40 4
      src/pages/iot-card/CardManagement/ImportModal.tsx
  17. 5 5
      src/pages/link/DashBoard/index.tsx
  18. 7 0
      src/pages/notice/Config/Debug/index.tsx
  19. 10 3
      src/pages/notice/Template/Detail/index.tsx
  20. 3 2
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/WriteProperty.tsx
  21. 6 4
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/index.tsx
  22. 1 1
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/index.tsx
  23. 6 0
      src/pages/rule-engine/Scene/Save/action/ListItem/FilterCondition.tsx
  24. 6 3
      src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx
  25. 7 2
      src/pages/rule-engine/Scene/Save/terms/paramsItem.tsx
  26. 1 1
      src/pages/system/Apply/index.tsx
  27. 1 1
      src/pages/system/Department/Assets/deivce/bind.tsx
  28. 1 2
      src/pages/system/Menu/Detail/edit.tsx
  29. 1 1
      src/pages/system/Menu/Setting/baseMenu.ts
  30. 2 1
      src/pages/system/Platforms/Api/base.tsx
  31. 30 10
      src/pages/system/Platforms/Api/basePage.tsx
  32. 46 46
      src/pages/system/Platforms/View/index.tsx
  33. 3 0
      src/utils/menu/index.ts
  34. 1 0
      src/utils/menu/router.ts

+ 2 - 2
config/proxy.ts

@@ -17,8 +17,8 @@ export default {
       // 测试环境
       target: 'http://120.77.179.54:8844/',
       ws: 'ws://120.77.179.54:8844/',
-      // target: 'http://192.168.32.65:8844/',
-      // ws: 'ws://192.168.32.65:8844/',
+      // target: 'http://192.168.32.86:8844/',
+      // ws: 'ws://192.168.32.86:8844/',
       //v2环境
       // ws: 'ws://47.109.52.230:8844',
       // target: 'http://47.109.52.230:8844',

+ 5 - 2
src/components/Player/ScreenPlayer.tsx

@@ -324,7 +324,10 @@ export default forwardRef((props: ScreenProps, ref) => {
                 {/*  <QuestionCircleOutlined />*/}
                 {/*</Tooltip>*/}
               </div>
-              <div className={'screen-tool-save'}>
+              <div
+                className={'screen-tool-save'}
+                style={{ display: 'flex', flexDirection: 'row-reverse', alignItems: 'center' }}
+              >
                 <Popover
                   content={
                     <Form style={{ width: '217px' }} form={historyForm}>
@@ -353,7 +356,7 @@ export default forwardRef((props: ScreenProps, ref) => {
                         type={'primary'}
                         onClick={saveHistory}
                         loading={loading}
-                        style={{ width: '100%', marginTop: 16 }}
+                        style={{ width: '100%', marginRight: 16 }}
                       >
                         保存
                       </Button>

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

@@ -237,7 +237,7 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
                   f.setFieldState(typeFiled.query('.termType'), async (state) => {
                     state.value = 'eq';
                     state.dataSource = termType;
-                    if (_field?.dataIndex === 'state') {
+                    if (_field?.dataIndex === 'state' || _field?.dataIndex === 'status') {
                       state.dataSource = [
                         { label: '=', value: 'eq' },
                         { label: '!=', value: 'not' },

+ 66 - 22
src/pages/DataCollect/Channel/Save/index.tsx

@@ -19,15 +19,11 @@ interface Props {
 export default (props: Props) => {
   const [data, setData] = useState<Partial<ChannelItem>>(props.data);
   const [authTypeList, setAuthTypeList] = useState<any[]>([]);
+  const [providerList, setProviderList] = useState<any[]>([]);
+  const [securityModesList, setSecurityModesList] = useState<any[]>([]);
+  const [securityPolicyList, setSecurityPolicyList] = useState<any[]>([]);
 
-  useEffect(() => {
-    if (props.data?.id) {
-      service.queryChannelByID(props.data.id).then((resp) => {
-        if (resp.status === 200) {
-          setData(resp.result);
-        }
-      });
-    }
+  const getAuth = () => {
     service.queryAuthTypeList({}).then((resp) => {
       if (resp.status === 200) {
         setAuthTypeList(
@@ -40,6 +36,61 @@ export default (props: Props) => {
         );
       }
     });
+  };
+
+  const getSecurityModesList = async () => {
+    const res = await service.querySecurityModesList({});
+    if (res.status === 200) {
+      const list = res.result.map((item: any) => ({
+        label: item,
+        value: item,
+      }));
+      setSecurityModesList(list);
+    }
+  };
+
+  const getSecurityPolicyList = async () => {
+    const res = await service.querySecurityPolicyList({});
+    if (res.status === 200) {
+      const list = res.result.map((item: any) => ({
+        label: item,
+        value: item,
+      }));
+      setSecurityPolicyList(list);
+    }
+  };
+
+  const getProviders = () => {
+    service.getProviders().then((resp) => {
+      if (resp.status === 200) {
+        const list = [
+          { label: 'OPC UA', value: 'OPC_UA' },
+          { label: 'Modbus TCP', value: 'MODBUS_TCP' },
+        ];
+        const arr = resp.result
+          .filter((item: any) => item.id === 'modbus-tcp' || item.id === 'opc-ua')
+          .map((it: any) => (it?.id === 'opc-ua' ? 'OPC_UA' : 'MODBUS_TCP'));
+        const providers = list.filter((item: any) => arr.includes(item.value));
+        setProviderList(providers);
+        if (arr.includes('OPC_UA')) {
+          getAuth();
+          getSecurityModesList();
+          getSecurityPolicyList();
+        }
+        // console.log('providers---',providers)
+      }
+    });
+  };
+
+  useEffect(() => {
+    if (props.data?.id) {
+      service.queryChannelByID(props.data.id).then((resp) => {
+        if (resp.status === 200) {
+          setData(resp.result);
+        }
+      });
+    }
+    getProviders();
   }, [props.data]);
 
   const form = createForm({
@@ -47,8 +98,8 @@ export default (props: Props) => {
     initialValues: data || {},
   });
 
-  const getSecurityPolicyList = () => service.querySecurityPolicyList({});
-  const getSecurityModesList = () => service.querySecurityModesList({});
+  // const getSecurityPolicyList = () => service.querySecurityPolicyList({});
+  // const getSecurityModesList = () => service.querySecurityModesList({});
   const getCertificateList = () => service.queryCertificateList({});
 
   const useAsyncDataSource = (services: (arg0: Field) => Promise<any>) => (field: Field) => {
@@ -138,16 +189,7 @@ export default (props: Props) => {
               placeholder: '请选择通讯协议',
             },
             'x-disabled': props.data?.id,
-            enum: [
-              { label: 'OPC UA', value: 'OPC_UA' },
-              { label: 'Modbus TCP', value: 'MODBUS_TCP' },
-            ],
-            'x-validator': [
-              {
-                required: true,
-                message: '请选择通讯协议',
-              },
-            ],
+            enum: providerList,
           },
           'configuration.host': {
             title: 'Modbus主机IP',
@@ -275,8 +317,9 @@ export default (props: Props) => {
                 message: '请选择安全策略',
               },
             ],
+            enum: securityPolicyList,
             'x-reactions': [
-              '{{useAsyncDataSource(getSecurityPolicyList)}}',
+              // '{{useAsyncDataSource(getSecurityPolicyList)}}',
               {
                 dependencies: ['..provider'],
                 fulfill: {
@@ -303,8 +346,9 @@ export default (props: Props) => {
                 message: '请选择安全模式',
               },
             ],
+            enum: securityModesList,
             'x-reactions': [
-              '{{useAsyncDataSource(getSecurityModesList)}}',
+              // '{{useAsyncDataSource(getSecurityModesList)}}',
               {
                 dependencies: ['..provider'],
                 fulfill: {

+ 1 - 1
src/pages/DataCollect/Collector/components/Point/Save/modbus.tsx

@@ -42,7 +42,7 @@ export default (props: Props) => {
         ...props.data?.configuration,
         parameter: {
           ...props.data?.configuration?.parameter,
-          writeByteCount: [props.data?.configuration?.parameter?.writeByteCount],
+          writeByteCount: props.data?.configuration?.parameter?.writeByteCount,
         },
       },
       nspwc:

+ 10 - 4
src/pages/DataCollect/Dashboard/index.tsx

@@ -105,10 +105,11 @@ const DeviceBoard = () => {
           format: 'HH:mm',
         };
       default:
-        console.log('swich---');
         const time = dt.end - dt.start;
         const hour = 60 * 60 * 1000;
         const days = hour * 24;
+        const year = days * 365;
+        // console.log('month---',month);
         if (time <= hour) {
           return {
             limit: Math.abs(Math.ceil(time / (60 * 60))),
@@ -121,6 +122,12 @@ const DeviceBoard = () => {
             interval: '1h',
             format: 'HH:mm',
           };
+        } else if (time >= year) {
+          return {
+            limit: Math.abs(Math.ceil(time / days / 31)) + 1,
+            interval: '1M',
+            format: 'yyyy年-M月',
+          };
         } else {
           return {
             limit: Math.abs(Math.ceil(time / days)) + 1,
@@ -133,7 +140,6 @@ const DeviceBoard = () => {
 
   const getEcharts = async () => {
     const data = ref.current!.getValues();
-    console.log('data---', data);
     const res = await service.dashboard([
       {
         dashboard: 'collector',
@@ -167,8 +173,8 @@ const DeviceBoard = () => {
         grid: {
           top: '2%',
           bottom: '5%',
-          left: '65px',
-          right: 0,
+          left: '55px',
+          right: '2.5%',
         },
         series: [
           {

+ 4 - 0
src/pages/DataCollect/service.ts

@@ -174,6 +174,10 @@ class Service {
       method: 'GET',
       params: data,
     });
+  public getProviders = () =>
+    request(`/${SystemConst.API_BASE}/gateway/device/providers`, {
+      method: 'GET',
+    });
 }
 
 const service = new Service();

+ 10 - 2
src/pages/Log/Access/index.tsx

@@ -10,6 +10,7 @@ import { useIntl } from '@@/plugin-locale/localeExports';
 import SearchComponent from '@/components/SearchComponent';
 import Detail from '@/pages/Log/Access/Detail';
 import { useDomFullHeight } from '@/hooks';
+import { Ellipsis } from '@/components';
 
 const service = new BaseService('logger/access');
 
@@ -96,9 +97,16 @@ const Access = () => {
         defaultMessage: '请求用户',
       }),
       dataIndex: 'context.username',
-      width: 100,
+      width: 200,
       render: (text, record: any) =>
-        record?.context?.username ? <Tag color="geekblue">{record?.context?.username}</Tag> : '',
+        record?.context?.username ? (
+          <Tag color="geekblue">
+            {/* {record?.context?.username} */}
+            <Ellipsis title={record?.context?.username} style={{ maxWidth: 170 }} />
+          </Tag>
+        ) : (
+          ''
+        ),
     },
     {
       title: intl.formatMessage({

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

@@ -24,6 +24,7 @@ const Tags = () => {
   useEffect(() => {
     if (tag) {
       setTags([...tag] || []);
+      console.log(tag);
     }
   }, [tag]);
 
@@ -59,7 +60,13 @@ const Tags = () => {
           <Descriptions.Item span={1} label={`${item.name}(${item.key})`} key={item.key}>
             <Tooltip title={item.value || ''} placement="topLeft">
               <div className="ellipsis" style={{ maxWidth: 300 }}>
-                {item.value || ''}
+                {/* {item.value || ''} */}
+                {item.type === 'enum'
+                  ? `${
+                      item?.dataType?.elements?.find((it: any) => it.value === item.value)?.text ||
+                      ''
+                    }`
+                  : `${item.value || ''}`}
               </div>
             </Tooltip>
           </Descriptions.Item>

+ 5 - 0
src/pages/device/Instance/service.ts

@@ -399,6 +399,11 @@ class Service extends BaseService<DeviceInstance> {
     request(`/${SystemConst.API_BASE}/edge/remote/${deviceId}/url`, {
       method: 'GET',
     });
+  public _stopControl = (deviceId: string) =>
+    request(`/${SystemConst.API_BASE}/edge/remote/${deviceId}/stop`, {
+      method: 'POST',
+      data: {},
+    });
 }
 
 export default Service;

+ 32 - 10
src/pages/device/Product/Detail/Access/index.tsx

@@ -626,11 +626,12 @@ const Access = () => {
           <Col span={12}>
             <div className={styles.config}>
               <div className={styles.item}>
-                <TitleComponent
-                  data={
-                    <span>
-                      接入方式
-                      <Tooltip
+                <div style={{ display: 'flex', width: 150, alignItems: 'flex-start' }}>
+                  <TitleComponent
+                    data={
+                      <span>
+                        接入方式
+                        {/* <Tooltip
                         title={
                           !!(productModel.current?.count && productModel.current?.count > 0)
                             ? '产品下有设备实例时不能更换接入方式'
@@ -651,13 +652,34 @@ const Access = () => {
                         >
                           更换
                         </Button>
-                      </Tooltip>
-                      {/* <Button onClick={async()=>{
+                      </Tooltip> */}
+                        {/* <Button onClick={async()=>{
                           await service.productGuideDetail()
                         }}>删除</Button> */}
-                    </span>
-                  }
-                />
+                      </span>
+                    }
+                  />
+                  <Tooltip
+                    title={
+                      !!(productModel.current?.count && productModel.current?.count > 0)
+                        ? '产品下有设备实例时不能更换接入方式'
+                        : ''
+                    }
+                  >
+                    <Button
+                      size="small"
+                      type="primary"
+                      ghost
+                      style={{ marginLeft: 20 }}
+                      disabled={!!(productModel.current?.count && productModel.current?.count > 0)}
+                      onClick={() => {
+                        setConfigVisible(true);
+                      }}
+                    >
+                      更换
+                    </Button>
+                  </Tooltip>
+                </div>
                 <div className={styles.context}>
                   {/*<Tooltip placement="topLeft" title={access?.name}>*/}
                   {/*  <div className="ellipsis-70">{access?.name}</div>*/}

+ 45 - 0
src/pages/edge/Device/Remote/index.tsx

@@ -0,0 +1,45 @@
+import { useLocation } from '@/hooks';
+import { PageContainer } from '@ant-design/pro-layout';
+import { useEffect, useState } from 'react';
+import { service } from '@/pages/device/Instance';
+
+const Remote = () => {
+  const location = useLocation();
+  const [url, setUrl] = useState<string>('');
+
+  const _stop = async (id: string) => await service._stopControl(id);
+
+  useEffect(() => {
+    const params = new URLSearchParams(location.search);
+    const deviceId = params.get('id');
+    if (deviceId) {
+      service._control(deviceId).then((resp: any) => {
+        if (resp.status === 200) {
+          console.log(resp.result);
+          const item = `http://${resp.result?.url}/#/login?token=${resp.result.token}`;
+          setUrl(item);
+        }
+      });
+    }
+    return () => {
+      if (deviceId) {
+        _stop(deviceId);
+      }
+    };
+  }, [location]);
+
+  return (
+    <PageContainer>
+      {/* 远程控制 */}
+      <iframe
+        src={url}
+        style={{
+          width: '100%',
+          height: 'calc(100vh - 20vh)',
+        }}
+      ></iframe>
+    </PageContainer>
+  );
+};
+
+export default Remote;

+ 21 - 11
src/pages/edge/Device/index.tsx

@@ -80,11 +80,16 @@ export default () => {
     <PermissionButton
       type={'link'}
       onClick={() => {
-        service._control(record.id).then((resp: any) => {
-          if (resp.status === 200) {
-            window.open(resp.result);
-          }
-        });
+        const url = getMenuPathByParams(MENUS_CODE['edge/Device/Remote']);
+        history.push(`${url}?id=${record?.id}`);
+        // service._control(record.id).then((resp: any) => {
+        //   if (resp.status === 200) {
+        //     window.open(resp.result);
+        //   }
+        // });
+      }}
+      tooltip={{
+        title: type === 'list' ? '远程控制' : '',
       }}
       isPermission={permission.setting}
       style={{ padding: 0 }}
@@ -102,7 +107,7 @@ export default () => {
       isPermission={permission.password}
       key={'reset'}
       popConfirm={{
-        title: '确认重置密码?',
+        title: '确认重置密码为P@ssw0rd?',
         onConfirm: () => {
           service.restPassword(record.id).then((resp: any) => {
             if (resp.status === 200) {
@@ -162,10 +167,15 @@ export default () => {
       }}
       isPermission={permission.action}
       tooltip={{
-        title: intl.formatMessage({
-          id: `pages.data.option.${record.state.value !== 'notActive' ? 'disabled' : 'enabled'}`,
-          defaultMessage: record.state.value !== 'notActive' ? '禁用' : '启用',
-        }),
+        title:
+          type === 'list'
+            ? intl.formatMessage({
+                id: `pages.data.option.${
+                  record.state.value !== 'notActive' ? 'disabled' : 'enabled'
+                }`,
+                defaultMessage: record.state.value !== 'notActive' ? '禁用' : '启用',
+              })
+            : '',
       }}
     >
       {record.state.value !== 'notActive' ? <StopOutlined /> : <PlayCircleOutlined />}
@@ -185,7 +195,7 @@ export default () => {
       tooltip={
         record.state.value !== 'notActive'
           ? { title: intl.formatMessage({ id: 'pages.device.instance.deleteTip' }) }
-          : undefined
+          : { title: type !== 'list' ? '' : '删除' }
       }
       disabled={record.state.value !== 'notActive'}
       popConfirm={{

+ 1 - 1
src/pages/edge/Resource/index.tsx

@@ -267,7 +267,7 @@ export default () => {
           status: 'enabled',
         },
         disabled: {
-          text: '异常',
+          text: '禁用',
           status: 'disabled',
         },
       },

+ 46 - 46
src/pages/home/Api/index.tsx

@@ -1,8 +1,8 @@
-import { Button, Card, Col, Input, Popover, Row } from 'antd';
+import { Card, Col, Row } from 'antd';
 import { useEffect, useState } from 'react';
 import { service } from '@/pages/system/Platforms';
 import Service from '../service';
-import * as moment from 'moment';
+// import * as moment from 'moment';
 import ApiPage from '@/pages/system/Platforms/Api/base';
 
 const defaultHeight = 50;
@@ -11,7 +11,7 @@ export default () => {
   const api = new Service();
   const [clientId, setClientId] = useState('');
   const [secureKey, setSecureKey] = useState('');
-  const [sdkDetail, setSdkDetail] = useState<any>({});
+  // const [sdkDetail, setSdkDetail] = useState<any>({});
   const [loading, setLoading] = useState<boolean>(false);
 
   const getDetail = async (id: string) => {
@@ -25,29 +25,29 @@ export default () => {
     }
   };
 
-  const getSDKDetail = async () => {
-    const resp = await service.getSdk();
-    if (resp.status === 200) {
-      setSdkDetail(resp.result[0]);
-    }
-  };
+  // const getSDKDetail = async () => {
+  //   const resp = await service.getSdk();
+  //   if (resp.status === 200) {
+  //     setSdkDetail(resp.result[0]);
+  //   }
+  // };
 
-  const downLoad = (url: string) => {
-    if (url) {
-      const downNode = document.createElement('a');
-      downNode.href = url;
-      downNode.download = `${moment(new Date()).format('YYYY-MM-DD-HH-mm-ss')}.sdk`;
-      downNode.style.display = 'none';
-      downNode.setAttribute('target', '_blank');
-      document.body.appendChild(downNode);
-      downNode.click();
-      document.body.removeChild(downNode);
-    }
-  };
+  // const downLoad = (url: string) => {
+  //   if (url) {
+  //     const downNode = document.createElement('a');
+  //     downNode.href = url;
+  //     downNode.download = `${moment(new Date()).format('YYYY-MM-DD-HH-mm-ss')}.sdk`;
+  //     downNode.style.display = 'none';
+  //     downNode.setAttribute('target', '_blank');
+  //     document.body.appendChild(downNode);
+  //     downNode.click();
+  //     document.body.removeChild(downNode);
+  //   }
+  // };
 
   useEffect(() => {
     //  请求SDK下载地址
-    getSDKDetail();
+    // getSDKDetail();
     api.userDetail().then((res) => {
       if (res.status === 200) {
         api.apiDetail(res.result.id).then((response) => {
@@ -60,28 +60,28 @@ export default () => {
     });
   }, []);
 
-  const downLoadJDK = (
-    <div>
-      <div
-        style={{
-          width: 500,
-          borderRadius: 2,
-          marginBottom: 12,
-        }}
-      >
-        <Input.TextArea value={sdkDetail?.dependency} rows={6} readOnly />
-      </div>
-      <Button
-        type={'primary'}
-        style={{ width: '100%' }}
-        onClick={() => {
-          downLoad(sdkDetail.sdk);
-        }}
-      >
-        jar下载
-      </Button>
-    </div>
-  );
+  // const downLoadJDK = (
+  //   <div>
+  //     <div
+  //       style={{
+  //         width: 500,
+  //         borderRadius: 2,
+  //         marginBottom: 12,
+  //       }}
+  //     >
+  //       <Input.TextArea value={sdkDetail?.dependency} rows={6} readOnly />
+  //     </div>
+  //     <Button
+  //       type={'primary'}
+  //       style={{ width: '100%' }}
+  //       onClick={() => {
+  //         downLoad(sdkDetail.sdk);
+  //       }}
+  //     >
+  //       jar下载
+  //     </Button>
+  //   </div>
+  // );
 
   return (
     <Row gutter={[16, 16]}>
@@ -101,7 +101,7 @@ export default () => {
               </div>
             </Card>
           </Col>
-          <Col span={12}>
+          {/* <Col span={12}>
             <Card title="SDK下载">
               <div style={{ height: defaultHeight }}>
                 <Popover trigger="click" title={'POM依赖'} content={downLoadJDK}>
@@ -109,7 +109,7 @@ export default () => {
                 </Popover>
               </div>
             </Card>
-          </Col>
+          </Col> */}
         </Row>
       </Col>
       <Col span={24}>

+ 40 - 4
src/pages/iot-card/CardManagement/ImportModal.tsx

@@ -4,7 +4,7 @@ import { useRequest } from 'ahooks';
 import { service } from '@/pages/iot-card/CardManagement/index';
 import Token from '@/utils/token';
 import SystemConst from '@/utils/const';
-import { downloadFile } from '@/utils/util';
+import { downloadFile, onlyMessage } from '@/utils/util';
 import { CheckOutlined } from '@ant-design/icons';
 
 type ImportModalType = {
@@ -17,6 +17,7 @@ const ImportModal = (props: ImportModalType) => {
   const [configId, setConfigId] = useState('');
   const [total, setTotal] = useState(0);
   const [loading, setLoading] = useState(false);
+  const [form] = Form.useForm();
 
   const { data: platformList, run: platformRun } = useRequest(service.queryPlatformNoPage, {
     manual: true,
@@ -47,6 +48,9 @@ const ImportModal = (props: ImportModalType) => {
       const resp = info.file.response || { result: '' };
       submitData(resp.result);
     }
+    if (!info.file.status) {
+      setLoading(false);
+    }
   };
 
   const downFileFn = (type: string) => {
@@ -62,9 +66,26 @@ const ImportModal = (props: ImportModalType) => {
   }, []);
 
   return (
-    <Modal title={'导入'} visible={true} onOk={props.onCancel} onCancel={props.onCancel}>
-      <Form layout={'vertical'}>
-        <Form.Item label={'平台对接'}>
+    <Modal
+      title={'导入'}
+      visible={true}
+      onOk={async () => {
+        // props.onCancel()
+        const res = await form.validateFields();
+        if (res) {
+          props.onCancel();
+          // console.log(res)
+        }
+      }}
+      onCancel={props.onCancel}
+    >
+      <Form layout={'vertical'} form={form}>
+        <Form.Item
+          label={'平台对接'}
+          name={'platform'}
+          required
+          rules={[{ required: true, message: '请选择平台对接' }]}
+        >
           <Select
             showSearch
             placeholder={'请选择平台对接'}
@@ -106,6 +127,21 @@ const ImportModal = (props: ImportModalType) => {
                 }}
                 showUploadList={false}
                 onChange={fileChange}
+                beforeUpload={(file) => {
+                  const type = fileType === 'csv' ? 'csv' : 'xlsx';
+
+                  const isCsv = file.type === 'text/csv';
+                  const isXlsx =
+                    file.type ===
+                    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
+                  if (!isCsv && type !== 'xlsx') {
+                    onlyMessage('请上传.csv格式文件', 'warning');
+                  }
+                  if (!isXlsx && type !== 'csv') {
+                    onlyMessage('请上传.xlsx格式文件', 'warning');
+                  }
+                  return (isCsv && type !== 'xlsx') || (isXlsx && type !== 'csv');
+                }}
               >
                 <Button loading={loading}>上传文件</Button>
               </Upload>

+ 5 - 5
src/pages/link/DashBoard/index.tsx

@@ -250,7 +250,7 @@ export default () => {
       xAxis: {
         type: 'category',
         data: xAxis,
-        boundaryGap: false,
+        boundaryGap: true,
       },
       tooltip: {
         trigger: 'axis',
@@ -260,8 +260,8 @@ export default () => {
         type: 'value',
       },
       grid: {
-        left: 60,
-        right: 0,
+        left: 70,
+        right: 10,
         top: 10,
         bottom: 20,
       },
@@ -298,7 +298,7 @@ export default () => {
     setJvmOptions({
       xAxis: {
         type: 'category',
-        boundaryGap: false,
+        boundaryGap: true,
         data: arrayReverse(xAxis),
       },
       tooltip: {
@@ -359,7 +359,7 @@ export default () => {
     setCpuOptions({
       xAxis: {
         type: 'category',
-        boundaryGap: false,
+        boundaryGap: true,
         data: arrayReverse(xAxis),
       },
       tooltip: {

+ 7 - 0
src/pages/notice/Config/Debug/index.tsx

@@ -165,6 +165,13 @@ const Debug = observer(() => {
         required: true,
         'x-component': 'Select',
         'x-reactions': '{{useAsyncDataSource(getTemplate)}}',
+        'x-component-props': {
+          showSearch: true,
+          allowClear: true,
+          showArrow: true,
+          filterOption: (input: string, option: any) =>
+            option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0,
+        },
       },
       variableDefinitions: {
         title: '变量',

+ 10 - 3
src/pages/notice/Template/Detail/index.tsx

@@ -165,6 +165,7 @@ const Detail = observer(() => {
           });
           onFieldValueChange('type', async (field, f) => {
             const value = field.value;
+
             setTypeItem(value);
             if (!value) return;
             f.setFieldState('provider', (state1) => {
@@ -173,6 +174,12 @@ const Detail = observer(() => {
               }
               state1.dataSource = typeList[value];
             });
+            if (field.modified) {
+              // console.log('value------',value)
+              f.setFieldState('configId', (state2) => {
+                state2.value = undefined;
+              });
+            }
           });
           onFieldValueChange('provider', async (field, form1) => {
             const value = field.value;
@@ -1359,7 +1366,7 @@ const Detail = observer(() => {
                     'x-validator': [
                       {
                         required: true,
-                        message: '请输入签名',
+                        message: '请选择签名',
                       },
                     ],
                     'x-component': 'Select',
@@ -1368,7 +1375,7 @@ const Detail = observer(() => {
                       tooltip: '用于短信内容签名信息显示',
                     },
                     'x-component-props': {
-                      placeholder: '请输入签名',
+                      placeholder: '请选择签名',
                     },
                     'x-reactions': {
                       dependencies: ['configId'],
@@ -1590,7 +1597,7 @@ const Detail = observer(() => {
             message: '最多可输入500个字符',
           },
           {
-            require: true,
+            required: true,
             message: '请输入模版内容',
           },
         ],

+ 3 - 2
src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/WriteProperty.tsx

@@ -1,4 +1,5 @@
 import { Col, Row, Select } from 'antd';
+import { isBoolean } from 'lodash';
 import { useEffect, useRef, useState } from 'react';
 import TypeModel from './TypeModel';
 // import { useEffect, useState } from "react";
@@ -65,7 +66,7 @@ export default (props: Props) => {
   }, [props.properties]);
 
   useEffect(() => {
-    if (props.onChange && propertiesValue) {
+    if (props.onChange && (propertiesValue || isBoolean(propertiesValue))) {
       const obj = {
         [propertiesId || 0]: {
           value: propertiesValue,
@@ -143,7 +144,7 @@ export default (props: Props) => {
               }
             }}
             onChange={(value, sources, text) => {
-              console.log(value, sources);
+              // console.log(value, sources);
               // console.log(text);
               ref.current = text;
               setPropertiesValue(value);

+ 6 - 4
src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/index.tsx

@@ -7,6 +7,7 @@ import FunctionCall from './functionCall';
 import ReadProperty from './ReadProperty';
 import WriteProperty from './WriteProperty';
 import { service } from '@/pages/device/Instance/index';
+import { isBoolean } from 'lodash';
 
 interface Props {
   get: (data: any) => void;
@@ -194,9 +195,10 @@ export default observer((props: Props) => {
               // { required: true, message: '请选择属性' },
               () => ({
                 validator(_, value) {
-                  const isValue = Object.values(value)?.[0];
-                  // console.log('-------',isValue,value)
-                  if (isValue) {
+                  const isValue: any = Object.values(value)?.[0];
+                  console.log('-------', isValue, isBoolean(isValue?.value));
+
+                  if (isValue || isBoolean(isValue?.value)) {
                     return Promise.resolve();
                   }
                   return Promise.reject(new Error('请选择属性'));
@@ -217,7 +219,7 @@ export default observer((props: Props) => {
                 const item = value[Object.keys(value)?.[0]]?.value;
                 const item1 = value[Object.keys(value)?.[0]]?.upperKey;
                 const source = value[Object.keys(value)?.[0]]?.source;
-                console.log(value);
+                console.log('changeValue-------', value);
                 DeviceModel.propertiesName = text;
                 if (valueLable) {
                   DeviceModel.propertiesValue = valueLable;

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

@@ -148,7 +148,7 @@ export default observer((props: Props) => {
       _options.propertiesValue =
         typeof DeviceModel.propertiesValue === 'object'
           ? JSON.stringify(DeviceModel.propertiesValue)
-          : DeviceModel.propertiesValue;
+          : `${DeviceModel.propertiesValue}`;
       _options.columns = DeviceModel.columns;
       _options.otherColumns = DeviceModel.columns;
       const cur: any = Object.values(value.message.properties)?.[0];

+ 6 - 0
src/pages/rule-engine/Scene/Save/action/ListItem/FilterCondition.tsx

@@ -53,6 +53,7 @@ export default observer((props: FilterProps) => {
 
   const [deleteVisible, setDeleteVisible] = useState(false);
   const columnsRef = useRef<string[]>([]);
+  const oldLableRef = useRef<any>();
 
   const ValueRef = useRef<Partial<TermsType>>({
     column: '',
@@ -82,6 +83,7 @@ export default observer((props: FilterProps) => {
     (columnValue?: string) => {
       if (columnValue) {
         const labelOptions = columnOptionsMap.get(columnValue);
+        console.log('labelOptions------', labelOptions, props.data);
         if (labelOptions) {
           const _termTypeOptions: any[] =
             labelOptions?.termTypes?.map((tItem: any) => ({ title: tItem.name, key: tItem.id })) ||
@@ -140,6 +142,10 @@ export default observer((props: FilterProps) => {
 
   useEffect(() => {
     labelCache.current = props.label || [undefined, undefined, {}, 'and'];
+    console.log('labelCache.current-------', props.label);
+    if (props.label) {
+      oldLableRef.current = props.label;
+    }
   }, [props.label]);
 
   useEffect(() => {

+ 6 - 3
src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx

@@ -6,7 +6,7 @@ import './index.less';
 import TriggerAlarm from '../TriggerAlarm';
 import { AddButton } from '@/pages/rule-engine/Scene/Save/components/Buttons';
 import FilterGroup from './FilterGroup';
-import { cloneDeep, flattenDeep, set } from 'lodash';
+import { cloneDeep, flattenDeep, isBoolean, set } from 'lodash';
 import { Popconfirm, Space } from 'antd';
 import { TermsType } from '@/pages/rule-engine/Scene/typings';
 import { FormModel } from '@/pages/rule-engine/Scene/Save';
@@ -236,8 +236,11 @@ export default (props: ItemProps) => {
             <AIcon type={typeIconMap[data!.device!.message!.messageType]} />
             <span style={{ paddingRight: 4 }}>{data?.options?.type}</span>
             <AIcon type={'icon-mubiao'} style={{ paddingRight: 2 }} />
-            {`${data?.options?.name} ${data?.options?.properties} ${
-              data?.options?.propertiesValue ? `为 ${data?.options?.propertiesValue}` : ''
+            {`${data?.options?.name} ${data?.options?.properties} 
+            ${
+              (isBoolean(data?.options?.propertiesValue) ? true : data?.options?.propertiesValue)
+                ? `为 ${data?.options?.propertiesValue}`
+                : ''
             }`}
           </div>
         );

+ 7 - 2
src/pages/rule-engine/Scene/Save/terms/paramsItem.tsx

@@ -90,8 +90,13 @@ export const handleOptionsLabel = (data: any, type?: string) => {
         const str = termsTypeKey[t].replace('_value', _value[0]).replace('_value2', _value[1]);
         return `${c} ${str} ${typeStr} `;
       } else if (DoubleFilter.includes(t) && !!range && _value.length === 1) {
-        console.log(_value, range);
-        const str = termsTypeKey[t].replace('_value和_value2', _value[0]);
+        console.log(_value, range, t);
+        let str;
+        if (t === 'in' || t === 'nin') {
+          str = termsTypeKey[t].replace('_value,_value2', _value[0]);
+        } else {
+          str = termsTypeKey[t].replace('_value和_value2', _value[0]);
+        }
         return `${c} ${str} ${typeStr} `;
       } else {
         const str = termsTypeKey[t].replace('_value', _value[0]);

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

@@ -181,7 +181,7 @@ const Apply = () => {
         ) : null,
         isApiService(record.integrationModes) ? (
           <PermissionButton
-            key={'api'}
+            key={'viewApi'}
             type={'link'}
             style={{ padding: 0 }}
             isPermission={permission.update || permission.add}

+ 1 - 1
src/pages/system/Department/Assets/deivce/bind.tsx

@@ -374,7 +374,7 @@ const Bind = observer((props: Props) => {
             if (resp.status === 200) {
               newData = [...resp.result.data];
               const assetsResp = await service.getBindingAssets(
-                'product',
+                'device',
                 resp.result.data.map((item: any) => item.id),
               );
               if (assetsResp.status === 200) {

+ 1 - 2
src/pages/system/Menu/Detail/edit.tsx

@@ -167,10 +167,9 @@ export default (props: EditProps) => {
                     rules={[
                       { required: true, message: '请输入编码' },
                       { max: 64, message: '最多可输入64个字符' },
-
                       () => ({
                         async validator(_, value) {
-                          if (value) {
+                          if (value && value.length < 64) {
                             const res = await service.isCode({ code: value, owner: 'iot' });
                             if (res.result.passed) {
                               return Promise.resolve();

+ 1 - 1
src/pages/system/Menu/Setting/baseMenu.ts

@@ -2463,7 +2463,7 @@ export default [
             name: '网关设备',
             owner: 'iot',
             sortIndex: 1,
-            url: '/iot/edge/Devic',
+            url: '/iot/edge/Device',
             icon: 'icon-bumenguanli',
             showPage: ['edge-operations'],
             permissions: [

+ 2 - 1
src/pages/system/Platforms/Api/base.tsx

@@ -17,6 +17,7 @@ export const ApiModel = model<{
   components: any;
   swagger: any;
   debugger: any;
+  key?: any;
 }>({
   data: [],
   baseUrl: '',
@@ -80,7 +81,7 @@ export default observer((props: ApiPageProps) => {
         }
       });
     } else {
-      console.log(props.code, 1111111);
+      // console.log(props.code, 1111111);
       service.getApiGranted(code!).then((resp: any) => {
         if (resp.status === 200) {
           setGrantKeys(resp.result);

+ 30 - 10
src/pages/system/Platforms/Api/basePage.tsx

@@ -5,6 +5,7 @@ import { service } from '../index';
 import { ApiModel } from '@/pages/system/Platforms/Api/base';
 import { onlyMessage } from '@/utils/util';
 import PermissionButton from '@/components/PermissionButton';
+import _ from 'lodash';
 
 interface TableProps {
   data: any;
@@ -21,7 +22,7 @@ export default (props: TableProps) => {
   const [selectKeys, setSelectKeys] = useState<string[]>([]);
   const [dataSource, setDataSource] = useState<any[]>([]);
   const [loading, setLoading] = useState(false);
-  const [GrantKeys, setGrantKeys] = useState<string[] | undefined>(undefined);
+  const [GrantKeys, setGrantKeys] = useState<any>([]);
   const { permission } = PermissionButton.usePermission('system/Platforms/Setting');
 
   const grantCache = useRef<string[]>([]);
@@ -90,14 +91,14 @@ export default (props: TableProps) => {
     const code = param.get('code');
     // 和原有已授权数据进行对比
     const addGrant = selectKeys.filter((key) => {
-      if (grantCache.current.includes(key)) {
+      if (GrantKeys.includes(key)) {
         return false;
       }
       return true;
     });
 
     // 获取删除的数据
-    const removeGrant = grantCache.current.filter((key) => {
+    const removeGrant = GrantKeys.filter((key: any) => {
       if (selectKeys.includes(key)) {
         return false;
       }
@@ -124,9 +125,8 @@ export default (props: TableProps) => {
 
     setLoading(true);
     if (props.isOpenGranted === false) {
-      // console.log(props.grantKeys)
-      // console.log(addGrant,'add')
-      // console.log(removeGrant,'del')
+      // console.log('del-------', removeGrant);
+      // console.log('add-------', addGrant);
       const resp2 = removeGrant.length ? await service.apiOperationsRemove(removeGrant) : {};
       const resp = await service.apiOperationsAdd(addGrant);
       if (resp.status === 200 || resp2.status === 200) {
@@ -134,8 +134,12 @@ export default (props: TableProps) => {
         onlyMessage('操作成功');
       }
     } else {
-      const resp2 = await service.removeApiGrant(code!, { operations: removeOperations });
-      const resp = await service.addApiGrant(code!, { operations: addOperations });
+      const resp2 = await service.removeApiGrant(code!, {
+        operations: removeOperations.filter((item: any) => item.permissions),
+      });
+      const resp = await service.addApiGrant(code!, {
+        operations: addOperations.filter((item) => item.permissions),
+      });
       if (resp.status === 200 || resp2.status === 200) {
         getApiGrant();
         onlyMessage('操作成功');
@@ -144,6 +148,13 @@ export default (props: TableProps) => {
     setLoading(false);
   }, [selectKeys, location, dataSource, props.isOpenGranted]);
 
+  useEffect(() => {
+    // console.log('GrantKeys-=========', GrantKeys);
+    if (GrantKeys) {
+      setSelectKeys(GrantKeys);
+    }
+  }, [GrantKeys]);
+
   return (
     <div className={'platforms-api-table'}>
       <Table<any>
@@ -181,6 +192,7 @@ export default (props: TableProps) => {
             ? {
                 selectedRowKeys: selectKeys,
                 onSelect: (record, selected) => {
+                  console.log('selected----', selected);
                   if (selected) {
                     const newArr = [...selectKeys, record.operationId];
                     setSelectKeys(newArr);
@@ -189,6 +201,7 @@ export default (props: TableProps) => {
                   }
                 },
                 onSelectAll: (selected, selectedRows) => {
+                  // console.log('selectedRows',selected,selectedRows)
                   if (selected) {
                     // const items = selectedRows.filter((item) => !!item).map((item) => item.operationId).concat(props.grantKeys)
                     // console.log(items)
@@ -199,7 +212,14 @@ export default (props: TableProps) => {
                         .concat(GrantKeys),
                     );
                   } else {
-                    setSelectKeys([]);
+                    // setSelectKeys([]);
+                    // console.log(dataSource,GrantKeys)
+                    const diffList = _.difference(
+                      GrantKeys,
+                      dataSource.map((item) => item.operationId),
+                    );
+                    // console.log('diffList---',diffList)
+                    setSelectKeys(diffList);
                   }
                 },
               }
@@ -214,7 +234,7 @@ export default (props: TableProps) => {
             onClick={save}
             key={'update'}
             type={'primary'}
-            style={{ padding: 0, width: 50 }}
+            style={{ padding: 0, width: 80 }}
             loading={loading}
           >
             保存

+ 46 - 46
src/pages/system/Platforms/View/index.tsx

@@ -1,10 +1,10 @@
 import { PageContainer } from '@ant-design/pro-layout';
-import { Button, Card, Col, Input, Popover, Row } from 'antd';
+import { Card, Col, Row } from 'antd';
 import ApiPage from '../Api/base';
 import { useEffect, useState } from 'react';
 import { useLocation } from 'umi';
 import { service } from '@/pages/system/Platforms';
-import * as moment from 'moment';
+// import * as moment from 'moment';
 
 const defaultHeight = 50;
 
@@ -13,7 +13,7 @@ export default () => {
 
   const [clientId, setClientId] = useState('');
   const [secureKey, setSecureKey] = useState('');
-  const [sdkDetail, setSdkDetail] = useState<any>({});
+  // const [sdkDetail, setSdkDetail] = useState<any>({});
 
   const getDetail = async (id: string) => {
     const resp = await service.getDetail(id);
@@ -23,25 +23,25 @@ export default () => {
     }
   };
 
-  const getSDKDetail = async () => {
-    const resp = await service.getSdk();
-    if (resp.status === 200) {
-      setSdkDetail(resp.result[0]);
-    }
-  };
+  // const getSDKDetail = async () => {
+  //   const resp = await service.getSdk();
+  //   if (resp.status === 200) {
+  //     setSdkDetail(resp.result[0]);
+  //   }
+  // };
 
-  const downLoad = (url: string) => {
-    if (url) {
-      const downNode = document.createElement('a');
-      downNode.href = url;
-      downNode.download = `${moment(new Date()).format('YYYY-MM-DD-HH-mm-ss')}.sdk`;
-      downNode.style.display = 'none';
-      downNode.setAttribute('target', '_blank');
-      document.body.appendChild(downNode);
-      downNode.click();
-      document.body.removeChild(downNode);
-    }
-  };
+  // const downLoad = (url: string) => {
+  //   if (url) {
+  //     const downNode = document.createElement('a');
+  //     downNode.href = url;
+  //     downNode.download = `${moment(new Date()).format('YYYY-MM-DD-HH-mm-ss')}.sdk`;
+  //     downNode.style.display = 'none';
+  //     downNode.setAttribute('target', '_blank');
+  //     document.body.appendChild(downNode);
+  //     downNode.click();
+  //     document.body.removeChild(downNode);
+  //   }
+  // };
 
   useEffect(() => {
     const param = new URLSearchParams(location.search);
@@ -53,31 +53,31 @@ export default () => {
 
   useEffect(() => {
     //  请求SDK下载地址
-    getSDKDetail();
+    // getSDKDetail();
   }, []);
 
-  const downLoadJDK = (
-    <div>
-      <div
-        style={{
-          width: 500,
-          borderRadius: 2,
-          marginBottom: 12,
-        }}
-      >
-        <Input.TextArea value={sdkDetail?.dependency} rows={6} readOnly />
-      </div>
-      <Button
-        type={'primary'}
-        style={{ width: '100%' }}
-        onClick={() => {
-          downLoad(sdkDetail.sdk);
-        }}
-      >
-        jar下载
-      </Button>
-    </div>
-  );
+  // const downLoadJDK = (
+  //   <div>
+  //     <div
+  //       style={{
+  //         width: 500,
+  //         borderRadius: 2,
+  //         marginBottom: 12,
+  //       }}
+  //     >
+  //       <Input.TextArea value={sdkDetail?.dependency} rows={6} readOnly />
+  //     </div>
+  //     <Button
+  //       type={'primary'}
+  //       style={{ width: '100%' }}
+  //       onClick={() => {
+  //         downLoad(sdkDetail.sdk);
+  //       }}
+  //     >
+  //       jar下载
+  //     </Button>
+  //   </div>
+  // );
 
   return (
     <PageContainer>
@@ -98,7 +98,7 @@ export default () => {
                 </div>
               </Card>
             </Col>
-            <Col span={12}>
+            {/* <Col span={12}>
               <Card title="SDK下载">
                 <div style={{ height: defaultHeight }}>
                   <Popover trigger="click" title={'POM依赖'} content={downLoadJDK}>
@@ -106,7 +106,7 @@ export default () => {
                   </Popover>
                 </div>
               </Card>
-            </Col>
+            </Col> */}
           </Row>
         </Col>
         <Col span={24}>

+ 3 - 0
src/utils/menu/index.ts

@@ -89,6 +89,9 @@ const extraRouteObj = {
       { code: 'Save', name: '详情' },
     ],
   },
+  'edge/Device': {
+    children: [{ code: 'Remote', name: '远程控制' }],
+  },
 };
 //额外路由
 export const extraRouteArr = [

+ 1 - 0
src/utils/menu/router.ts

@@ -41,6 +41,7 @@ export enum MENUS_CODE {
   'DataCollect/Channel' = 'DataCollect/Channel',
   'DataCollect/Collector' = 'DataCollect/Collector',
   'edge/Device' = 'edge/Device',
+  'edge/Device/Remote' = 'edge/Device/Remote',
   'edge/Resource' = 'edge/Resource',
   'Log' = 'Log',
   'media/Cascade' = 'media/Cascade',