Преглед изворни кода

merge: merge next branch

merge: merge next branch
XieYongHong пре 3 година
родитељ
комит
a6f44a76bb
41 измењених фајлова са 568 додато и 178 уклоњено
  1. 3 1
      src/components/DashBoard/echarts.tsx
  2. 2 2
      src/components/DashBoard/timePicker.tsx
  3. 2 1
      src/components/Metadata/ArrayParam/index.tsx
  4. 24 1
      src/components/ProTableCard/CardItems/Scene/index.tsx
  5. 1 1
      src/components/ProTableCard/CardItems/edge/Resource.tsx
  6. 10 6
      src/components/SearchComponent/index.tsx
  7. 7 1
      src/pages/DataCollect/Collector/components/Point/Save/modbus.tsx
  8. 2 0
      src/pages/DataCollect/Dashboard/index.tsx
  9. 10 0
      src/pages/Northbound/DuerOS/Detail/index.tsx
  10. 1 1
      src/pages/account/Center/index.tsx
  11. 7 1
      src/pages/device/Firmware/Save/index.tsx
  12. 1 1
      src/pages/device/Firmware/Task/Detail/index.tsx
  13. 36 36
      src/pages/device/Firmware/Task/index.tsx
  14. 7 5
      src/pages/edge/Device/Save/index.tsx
  15. 5 3
      src/pages/edge/Device/index.tsx
  16. 2 2
      src/pages/edge/Resource/Issue/Result.tsx
  17. 16 3
      src/pages/edge/Resource/Issue/index.tsx
  18. 82 2
      src/pages/edge/Resource/index.tsx
  19. 2 1
      src/pages/home/components/CardStatics.tsx
  20. 1 0
      src/pages/init-home/components/menu.tsx
  21. 4 4
      src/pages/iot-card/Platform/Detail/index.tsx
  22. 32 26
      src/pages/link/AccessConfig/Detail/components/Network/index.tsx
  23. 24 21
      src/pages/link/AccessConfig/Detail/components/Protocol/index.tsx
  24. 1 1
      src/pages/media/Device/Channel/Live/index.less
  25. 1 0
      src/pages/media/Home/deviceModal.tsx
  26. 78 0
      src/pages/notice/Config/Detail/index.tsx
  27. 0 1
      src/pages/notice/Config/index.tsx
  28. 11 0
      src/pages/notice/Template/Debug/index.tsx
  29. 88 0
      src/pages/notice/Template/Detail/index.tsx
  30. 2 10
      src/pages/rule-engine/Alarm/Configuration/index.tsx
  31. 8 8
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/TypeModel.tsx
  32. 12 7
      src/pages/rule-engine/Scene/Save/action/ListItem/FilterCondition.tsx
  33. 4 1
      src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx
  34. 17 5
      src/pages/rule-engine/Scene/Save/components/Buttons/ParamsDropdown.tsx
  35. 13 4
      src/pages/rule-engine/Scene/Save/terms/paramsItem.tsx
  36. 1 1
      src/pages/rule-engine/Scene/typings.d.ts
  37. 16 2
      src/pages/system/Apply/Menu/index.tsx
  38. 14 15
      src/pages/system/Apply/Save/index.tsx
  39. 1 1
      src/pages/system/DataSource/Management/DataTable.tsx
  40. 3 3
      src/pages/system/Menu/Setting/baseMenu.ts
  41. 17 0
      src/utils/util.ts

+ 3 - 1
src/components/DashBoard/echarts.tsx

@@ -61,6 +61,7 @@ export default (props: EchartsProps) => {
   const [loading, setLoading] = useState(false);
 
   const initEcharts = (dom: HTMLDivElement) => {
+    console.log('------------init');
     if (!dom) return;
     chartsRef.current = chartsRef.current || echarts.init(dom);
     // chartsRef.current.clear()
@@ -98,10 +99,11 @@ export default (props: EchartsProps) => {
   }, [props.options, chartsRef.current]);
 
   useEffect(() => {
+    // console.log('------------init')
     if (loading) {
       setTimeout(() => {
         initEcharts(chartsDom.current);
-      }, 100);
+      }, 300);
     }
   }, [loading]);
 

+ 2 - 2
src/components/DashBoard/timePicker.tsx

@@ -12,7 +12,7 @@ export enum TimeKey {
   'year' = 'year',
 }
 
-export type TimeType = keyof typeof TimeKey;
+export type TimeType = keyof typeof TimeKey | undefined;
 
 type ValueType = { start: number; end: number; type: TimeType };
 
@@ -97,7 +97,7 @@ export default forwardRef((props: ExtraTimePickerProps, ref) => {
           onChange={(rangeValue) => {
             setRadioValue(undefined);
             if (rangeValue && rangeValue.length === 2) {
-              change(rangeValue[0]!.valueOf(), rangeValue[1]!.valueOf(), radioValue!);
+              change(rangeValue[0]!.valueOf(), rangeValue[1]!.valueOf(), undefined);
             }
             if (props.pickerTimeChange) {
               props.pickerTimeChange();

+ 2 - 1
src/components/Metadata/ArrayParam/index.tsx

@@ -1,5 +1,5 @@
 import { createSchemaField } from '@formily/react';
-import { Editable, FormItem, FormLayout, Input, NumberPicker, Select } from '@formily/antd';
+import { FormItem, FormLayout, Input, NumberPicker, Select } from '@formily/antd';
 import type { ISchema } from '@formily/json-schema';
 import './index.less';
 import { DataTypeList, DateTypeList, FileTypeList } from '@/pages/device/data';
@@ -7,6 +7,7 @@ import { Store } from 'jetlinks-store';
 import JsonParam from '@/components/Metadata/JsonParam';
 import EnumParam from '@/components/Metadata/EnumParam';
 import BooleanEnum from '@/components/Metadata/BooleanParam';
+import Editable from '../EditTable';
 
 interface Props {
   isFunction?: boolean;

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

@@ -12,6 +12,8 @@ import MyTooltip from './MyTooltip';
 import { handleOptionsLabel } from '@/pages/rule-engine/Scene/Save/terms/paramsItem';
 import { isArray } from 'lodash';
 import TriggerAlarm from '@/pages/rule-engine/Scene/Save/action/TriggerAlarm';
+import { getMenuPathByCode, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { history } from 'umi';
 
 const imageMap = new Map();
 imageMap.set('timer', require('/public/images/scene/scene-timer.png'));
@@ -58,7 +60,10 @@ const notifyRender = (data: ActionsType | undefined) => {
       }
       return (
         <span>
-          通过钉钉向{data?.options?.notifierName || data?.notify?.notifierId}发送
+          通过钉钉 向 {data?.options?.orgName || ''}
+          {data?.options?.tagName || ''}
+          {data?.options?.sendTo || ''}
+          发送
           {data?.options?.templateName || data?.notify?.templateId}
         </span>
       );
@@ -425,10 +430,28 @@ const TriggerRender = (data: SceneCardProps) => {
                 if (data.trigger?.device?.selector === 'fixed') {
                   // 自定义
                   //selectorValues
+                  if (!!getMenuPathByCode(MENUS_CODE['device/Instance'])) {
+                    const url = getMenuPathByParams(
+                      MENUS_CODE['device/Instance/Detail'],
+                      data.trigger?.device?.selectorValues[0]?.value,
+                    );
+                    if (url) {
+                      history.replace(url);
+                    }
+                  }
                 } else if (data.trigger?.device?.selector === 'org') {
                   // 组织
                 } else if (data.trigger?.device?.selector === 'all') {
                   // 产品
+                  if (!!getMenuPathByCode(MENUS_CODE['device/Product'])) {
+                    const url = getMenuPathByParams(
+                      MENUS_CODE['device/Product/Detail'],
+                      data.trigger?.device?.productId,
+                    );
+                    if (url) {
+                      history.replace(url);
+                    }
+                  }
                 }
               }
             }}

+ 1 - 1
src/components/ProTableCard/CardItems/edge/Resource.tsx

@@ -29,7 +29,7 @@ export default (props: ResourceCardProps) => {
         disabled: StatusColorEnum.error,
       }}
     >
-      <div className={'pro-table-card-item'}>
+      <div className={'pro-table-card-item'} onClick={props.onClick}>
         <div className={'card-item-avatar'}>
           <img width={88} height={88} src={defaultImage} alt={''} />
         </div>

+ 10 - 6
src/components/SearchComponent/index.tsx

@@ -211,12 +211,16 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
             const _column = (typeFiled as Field).value;
             const _field = field.find((item) => item.dataIndex === _column);
             if (_column === 'id') {
-              if (isModified) {
-                f.setFieldState(typeFiled.query('.termType'), async (state) => {
-                  state.value = 'eq';
-                  state.dataSource = termType;
-                });
-              }
+              f.setFieldState(typeFiled.query('.termType'), async (state) => {
+                state.value = 'eq';
+                state.dataSource = termType;
+              });
+              // if (isModified) {
+              //   f.setFieldState(typeFiled.query('.termType'), async (state) => {
+              //     state.value = 'eq';
+              //     state.dataSource = termType;
+              //   });
+              // }
               f.setFieldState(typeFiled.query('.value'), async (state) => {
                 state.componentType = 'Input';
                 state.componentProps = {

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

@@ -364,6 +364,10 @@ export default (props: Props) => {
             'x-decorator-props': {
               gridSpan: 2,
               layout: 'level',
+              style: {
+                marginBottom: '6px',
+                marginTop: '6px',
+              },
             },
             'x-component-props': {
               placeholder: '请选择非标准协议写入配置',
@@ -384,7 +388,7 @@ export default (props: Props) => {
               gridSpan: 2,
               style: {
                 backgroundColor: '#fafafa',
-                padding: 20,
+                padding: 6,
               },
             },
             'x-component': 'FormGrid',
@@ -420,6 +424,8 @@ export default (props: Props) => {
                     justifyContent: 'space-around',
                     minWidth: '130px',
                     height: '50px',
+                    marginBottom: '6px',
+                    marginTop: '6px',
                   },
                   options: [
                     { label: '是', value: true },

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

@@ -105,6 +105,7 @@ const DeviceBoard = () => {
           format: 'HH:mm',
         };
       default:
+        console.log('swich---');
         const time = dt.end - dt.start;
         const hour = 60 * 60 * 1000;
         const days = hour * 24;
@@ -132,6 +133,7 @@ const DeviceBoard = () => {
 
   const getEcharts = async () => {
     const data = ref.current!.getValues();
+    console.log('data---', data);
     const res = await service.dashboard([
       {
         dashboard: 'collector',

+ 10 - 0
src/pages/Northbound/DuerOS/Detail/index.tsx

@@ -252,6 +252,16 @@ const Save = () => {
           gridSpan: 1,
         },
         required: true,
+        'x-validator': [
+          {
+            max: 64,
+            message: '最多可输入64个字符',
+          },
+          {
+            required: true,
+            message: '请输入名称',
+          },
+        ],
         'x-component-props': {
           placeholder: '请输入名称',
         },

+ 1 - 1
src/pages/account/Center/index.tsx

@@ -197,7 +197,7 @@ const Center = () => {
           </div>
           <div className={styles.content}>
             <Descriptions column={4} layout="vertical" labelStyle={{ fontWeight: 600 }}>
-              <Descriptions.Item label="登录账号">{data?.username}</Descriptions.Item>
+              <Descriptions.Item label="用户名">{data?.username}</Descriptions.Item>
               <Descriptions.Item label="账号ID">
                 <Ellipsis title={data?.id} tooltip={{ placement: 'topLeft' }} maxWidth={'90%'} />
               </Descriptions.Item>

+ 7 - 1
src/pages/device/Firmware/Save/index.tsx

@@ -65,13 +65,19 @@ const Save = (props: Props) => {
         }
       });
       onFieldValueChange('versionOrder', async (field, f1) => {
+        console.log(data);
         const value = (field as Field).value;
         const productId = (field.query('.productId').take() as Field).value;
         if (field.modified && productId && value) {
           const resp = await service.validateVersion(productId, value);
           if (resp.status === 200) {
             f1.setFieldState('versionOrder', (state) => {
-              state.selfErrors = resp.result ? ['版本序号已存在'] : undefined;
+              if (data?.id && data.versionOrder === value) {
+                state.selfErrors = undefined;
+              } else {
+                state.selfErrors = resp.result ? ['版本序号已存在'] : undefined;
+              }
+              // state.selfErrors = resp.result ? ['版本序号已存在'] : undefined;
             });
           }
         }

+ 1 - 1
src/pages/device/Firmware/Task/Detail/index.tsx

@@ -298,7 +298,7 @@ const Detail = observer(() => {
                 style={{ padding: 0 }}
                 isPermission={permission.update}
                 tooltip={{
-                  title: '重试',
+                  title: '查看',
                 }}
                 onClick={() => {
                   setVisible(true);

+ 36 - 36
src/pages/device/Firmware/Task/index.tsx

@@ -6,7 +6,7 @@ import { useRef, useState } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import {
   ControlOutlined,
-  DeleteOutlined,
+  // DeleteOutlined,
   EyeOutlined,
   PlusOutlined,
   StopOutlined,
@@ -16,7 +16,7 @@ import { model } from '@formily/reactive';
 import { observer } from '@formily/react';
 import type { FirmwareItem } from '@/pages/device/Firmware/typings';
 import Save from './Save';
-import { onlyMessage } from '@/utils/util';
+// import { onlyMessage } from '@/utils/util';
 import { PermissionButton, AIcon } from '@/components';
 import useDomFullHeight from '@/hooks/document/useDomFullHeight';
 import usePermissions from '@/hooks/permission';
@@ -181,40 +181,40 @@ const Task = observer(() => {
           <EyeOutlined />
         </PermissionButton>,
         <UpgradeBtn data={record} actions={actionRef.current} key="btn" />,
-        <PermissionButton
-          key="delete"
-          type={'link'}
-          style={{ padding: 0 }}
-          isPermission={permission.delete}
-          tooltip={{
-            title: '删除',
-          }}
-          popConfirm={{
-            title:
-              record.waiting > 0 || record.processing > 0
-                ? '删除将导致正在进行的任务终止,确定要删除吗?'
-                : intl.formatMessage({
-                    id: 'pages.data.option.remove.tips',
-                    defaultMessage: '确认删除?',
-                  }),
-            onConfirm: async () => {
-              const resp = await service.deleteTask(record.id);
-              if (resp.status === 200) {
-                onlyMessage(
-                  intl.formatMessage({
-                    id: 'pages.data.option.success',
-                    defaultMessage: '操作成功!',
-                  }),
-                );
-                actionRef.current?.reload();
-              } else {
-                message.error(resp?.message || '删除失败!');
-              }
-            },
-          }}
-        >
-          <DeleteOutlined />
-        </PermissionButton>,
+        // <PermissionButton
+        //   key="delete"
+        //   type={'link'}
+        //   style={{ padding: 0 }}
+        //   isPermission={permission.delete}
+        //   tooltip={{
+        //     title: '删除',
+        //   }}
+        //   popConfirm={{
+        //     title:
+        //       record.waiting > 0 || record.processing > 0
+        //         ? '删除将导致正在进行的任务终止,确定要删除吗?'
+        //         : intl.formatMessage({
+        //             id: 'pages.data.option.remove.tips',
+        //             defaultMessage: '确认删除?',
+        //           }),
+        //     onConfirm: async () => {
+        //       const resp = await service.deleteTask(record.id);
+        //       if (resp.status === 200) {
+        //         onlyMessage(
+        //           intl.formatMessage({
+        //             id: 'pages.data.option.success',
+        //             defaultMessage: '操作成功!',
+        //           }),
+        //         );
+        //         actionRef.current?.reload();
+        //       } else {
+        //         message.error(resp?.message || '删除失败!');
+        //       }
+        //     },
+        //   }}
+        // >
+        //   <DeleteOutlined />
+        // </PermissionButton>,
       ],
     },
   ];

+ 7 - 5
src/pages/edge/Device/Save/index.tsx

@@ -258,7 +258,7 @@ const Save = (props: Props) => {
         </Row>
         <Row>
           <Col span={24}>
-            <Form.Item label={intlFormat('pages.table.description', '说明')} name={'description'}>
+            <Form.Item label={intlFormat('pages.table.description', '说明')} name={'describe'}>
               <Input.TextArea
                 placeholder={
                   intlFormat('pages.form.tip.input', '请输入') +
@@ -280,13 +280,15 @@ const Save = (props: Props) => {
           setVisible(false);
         }}
         deviceType={'gateway'}
-        reload={(productId: string, name: string) => {
-          form.setFieldsValue({ productId });
+        reload={(productId: string, result: any) => {
+          console.log('------', productId, result.name);
+
           productList.push({
-            id: productId,
-            name,
+            value: productId,
+            label: result.name,
           });
           setProductList([...productList]);
+          form.setFieldsValue({ productId: productId });
         }}
       />
     </Modal>

+ 5 - 3
src/pages/edge/Device/index.tsx

@@ -3,7 +3,7 @@ import { DeviceInstance } from '@/pages/device/Instance/typings';
 import SearchComponent from '@/components/SearchComponent';
 import { ActionType, ProColumns } from '@jetlinks/pro-table';
 import moment from 'moment';
-import { Badge, Button, Tooltip } from 'antd';
+import { Badge, Tooltip } from 'antd';
 import { service as categoryService } from '@/pages/device/Category';
 import { InstanceModel, service, statusMap } from '@/pages/device/Instance';
 import { useIntl } from '@@/plugin-locale/localeExports';
@@ -36,13 +36,15 @@ export default () => {
   const history = useHistory<Record<string, string>>();
   const [importVisible, setImportVisible] = useState<boolean>(false);
   const { permission } = PermissionButton.usePermission('edge/Device');
+  const devicePermission = PermissionButton.usePermission('device/Instance').permission;
 
   const tools = (record: DeviceInstance, type: 'card' | 'list') => [
     type === 'list' && (
-      <Button
+      <PermissionButton
         type={'link'}
         style={{ padding: 0 }}
         key={'detail'}
+        isPermission={permission.view && devicePermission.view}
         onClick={() => {
           InstanceModel.current = record;
           const url = getMenuPathByParams(MENUS_CODE['device/Instance/Detail'], record.id);
@@ -57,7 +59,7 @@ export default () => {
         >
           <EyeOutlined />
         </Tooltip>
-      </Button>
+      </PermissionButton>
     ),
     <PermissionButton
       type={'link'}

+ 2 - 2
src/pages/edge/Resource/Issue/Result.tsx

@@ -1,6 +1,6 @@
 import SystemConst from '@/utils/const';
 import Token from '@/utils/token';
-import { downloadObject } from '@/utils/util';
+import { downloadTxT } from '@/utils/util';
 import { Col, Input, Modal, Row } from 'antd';
 import { EventSourcePolyfill } from 'event-source-polyfill';
 import { useEffect, useState } from 'react';
@@ -90,7 +90,7 @@ const Publish = (props: Props) => {
               <a
                 style={{ marginLeft: 20 }}
                 onClick={() => {
-                  downloadObject(errMessage || '', '下发失败原因');
+                  downloadTxT(errMessage || '', '下发失败原因');
                 }}
               >
                 下载

+ 16 - 3
src/pages/edge/Resource/Issue/index.tsx

@@ -11,6 +11,7 @@ import styles from '@/pages/link/AccessConfig/Detail/components/Network/index.le
 import { InfoCircleOutlined } from '@ant-design/icons';
 import { onlyMessage } from '@/utils/util';
 import Result from './Result';
+import { service as api } from '@/pages/device/Instance';
 interface Props {
   data: Partial<ResourceItem>;
   cancel: () => void;
@@ -36,6 +37,15 @@ export default (props: Props) => {
       }),
       dataIndex: 'productName',
       ellipsis: true,
+      valueType: 'select',
+      index: 1,
+      request: async () => {
+        const res = await api.getProductList();
+        if (res.status === 200) {
+          return res.result.map((pItem: any) => ({ label: pItem.name, value: pItem.id }));
+        }
+        return [];
+      },
     },
     {
       title: intl.formatMessage({
@@ -50,9 +60,12 @@ export default (props: Props) => {
         id: 'pages.device.instance.registrationTime',
         defaultMessage: '注册时间',
       }),
-      dataIndex: 'registryTime',
+      dataIndex: 'registerTime',
       width: '200px',
-      render: (text: any) => (text ? moment(text).format('YYYY-MM-DD HH:mm:ss') : ''),
+      valueType: 'dateTime',
+      render: (_: any, row) => {
+        return row.createTime ? moment(row.registerTime).format('YYYY-MM-DD HH:mm:ss') : '';
+      },
       sorter: true,
     },
     {
@@ -179,7 +192,7 @@ export default (props: Props) => {
                 type: 'and',
               },
             ],
-            sorts: [{ name: 'createTime', order: 'desc' }],
+            sorts: [{ name: 'registerTime', order: 'desc' }],
           })
         }
       />

+ 82 - 2
src/pages/edge/Resource/index.tsx

@@ -18,6 +18,9 @@ import Issue from './Issue';
 import Service from './service';
 import ResourceCard from '@/components/ProTableCard/CardItems/edge/Resource';
 import moment from 'moment';
+import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import { useHistory } from 'umi';
+import { service as api } from '@/pages/device/Instance';
 
 export const service = new Service('entity/template');
 
@@ -30,6 +33,8 @@ export default () => {
   const [issueVisible, setIssueVisible] = useState<boolean>(false);
   const { permission } = PermissionButton.usePermission('edge/Resource');
 
+  const history = useHistory<Record<string, string>>();
+
   const tools = (record: ResourceItem, type: 'card' | 'list') => [
     <PermissionButton
       type={'link'}
@@ -57,7 +62,7 @@ export default () => {
       tooltip={{
         title:
           type !== 'list'
-            ? `${record.state.value === 'disabled' ? '请先启用,再下发' : undefined}`
+            ? `${record.state.value === 'disabled' ? '请先启用,再下发' : ''}`
             : '下发',
       }}
       style={{ padding: 0 }}
@@ -157,6 +162,7 @@ export default () => {
       dataIndex: 'id',
       width: 200,
       ellipsis: true,
+      hideInSearch: true,
       fixed: 'left',
     },
     {
@@ -170,12 +176,69 @@ export default () => {
       dataIndex: 'category',
       width: 150,
       ellipsis: true,
+      valueType: 'select',
+      valueEnum: {
+        OPC_UA: {
+          text: 'OPC UA接入',
+          status: 'OPC_UA',
+        },
+        MODBUS_TCP: {
+          text: 'Modbus TCP接入',
+          status: 'MODBUS_TCP',
+        },
+        snap7: {
+          text: 'S7-200接入',
+          status: 'snap7',
+        },
+        BACNetIp: {
+          text: 'BACnet接入',
+          status: 'BACNetIp',
+        },
+        MODBUS_RTU: {
+          text: 'MODBUS_RTU接入',
+          status: 'MODBUS_RTU',
+        },
+      },
     },
     {
       title: '所属边缘网关',
       width: 150,
       dataIndex: 'sourceId',
       ellipsis: true,
+      valueType: 'select',
+      hideInTable: true,
+      request: async () => {
+        const res: any = await api.queryNoPagingPost({
+          terms: [
+            {
+              terms: [
+                {
+                  column: 'productId$product-info',
+                  value: 'accessProvider is official-edge-gateway',
+                },
+              ],
+              type: 'and',
+            },
+          ],
+          sorts: [
+            {
+              name: 'createTime',
+              order: 'desc',
+            },
+          ],
+        });
+        if (res.status === 200) {
+          return res.result.map((pItem: any) => ({ label: pItem.name, value: pItem.id }));
+        }
+        return [];
+      },
+    },
+    {
+      title: '所属边缘网关',
+      width: 150,
+      dataIndex: 'sourceName',
+      ellipsis: true,
+      hideInSearch: true,
     },
     {
       title: '创建时间',
@@ -253,7 +316,24 @@ export default () => {
         rowKey="id"
         search={false}
         pagination={{ pageSize: 10 }}
-        cardRender={(record) => <ResourceCard {...record} actions={tools(record, 'card')} />}
+        cardRender={(record) => (
+          <ResourceCard
+            {...record}
+            onClick={() => {
+              const url = getMenuPathByParams(
+                MENUS_CODE['device/Instance/Detail'],
+                record.sourceId,
+              );
+              console.log(url);
+              if (url) {
+                history.push(url);
+              } else {
+                onlyMessage('暂无权限,请联系管理员', 'warning');
+              }
+            }}
+            actions={tools(record, 'card')}
+          />
+        )}
       />
       {visible && (
         <Save

+ 2 - 1
src/pages/home/components/CardStatics.tsx

@@ -8,6 +8,7 @@ type StatisticsItem = {
   children: React.ReactNode | string;
   permission?: any;
   node?: any;
+  style?: any;
 };
 
 interface StatisticsProps {
@@ -48,7 +49,7 @@ const CardStatistics = (props: StatisticsProps) => {
             ) : (
               <div
                 className={'item-index-echarts'}
-                style={item.style || { height: 75, width: 110 }}
+                style={item.style || { height: 75, width: 110, minHeight: 75 }}
               >
                 {item.children}
               </div>

+ 1 - 0
src/pages/init-home/components/menu.tsx

@@ -43,6 +43,7 @@ const Menu = forwardRef((props: { onChange?: (menu: any) => void }, ref) => {
         resp.result.map((item: any) => JSON.parse(item).id),
         BaseMenu,
       );
+      // console.log(newTree)
       const _count = menuCount(newTree);
       menuRef.current = newTree;
       setCount(_count);

+ 4 - 4
src/pages/iot-card/Platform/Detail/index.tsx

@@ -179,10 +179,10 @@ const Detail = observer(() => {
                   placeholder: '请输入接口地址',
                 },
                 'x-validator': [
-                  {
-                    max: 64,
-                    message: '最多可输入64个字符',
-                  },
+                  // {
+                  //   max: 64,
+                  //   message: '最多可输入64个字符',
+                  // },
                   {
                     required: true,
                     message: '请输入接口地址',

+ 32 - 26
src/pages/link/AccessConfig/Detail/components/Network/index.tsx

@@ -34,7 +34,14 @@ const Network = (props: Props) => {
   };
 
   useEffect(() => {
-    queryNetworkList(props.provider?.id, encodeQuery({ include: networkCurrent || '' }));
+    queryNetworkList(
+      props.provider?.id,
+      encodeQuery({
+        include: networkCurrent || '',
+        'sorts[0].name': 'id',
+        'sorts[0].value': networkCurrent,
+      }),
+    );
   }, [props.provider?.id]);
 
   useEffect(() => {
@@ -170,31 +177,30 @@ const Network = (props: Props) => {
             description={
               <span>
                 暂无数据
-                {getButtonPermission('link/Type', ['add']) ? (
-                  '请联系管理员进行配置'
-                ) : (
-                  <Button
-                    type="link"
-                    onClick={() => {
-                      const url = getMenuPathByCode(MENUS_CODE['link/Type/Detail']);
-                      const tab: any = window.open(
-                        `${origin}/#${url}?type=${
-                          NetworkTypeMapping.get(props.provider?.id) || ''
-                        }`,
-                      );
-                      tab!.onTabSaveSuccess = (value: any) => {
-                        if (value.status === 200) {
-                          setNetworkCurrent(value.result?.id);
-                          queryNetworkList(props.provider?.id, {
-                            include: networkCurrent || '',
-                          });
-                        }
-                      };
-                    }}
-                  >
-                    去新增
-                  </Button>
-                )}
+                {
+                  getButtonPermission('link/Type', ['add']) ? '请联系管理员进行配置' : ''
+                  // <Button
+                  //   type="link"
+                  //   onClick={() => {
+                  //     const url = getMenuPathByCode(MENUS_CODE['link/Type/Detail']);
+                  //     const tab: any = window.open(
+                  //       `${origin}/#${url}?type=${
+                  //         NetworkTypeMapping.get(props.provider?.id) || ''
+                  //       }`,
+                  //     );
+                  //     tab!.onTabSaveSuccess = (value: any) => {
+                  //       if (value.status === 200) {
+                  //         setNetworkCurrent(value.result?.id);
+                  //         queryNetworkList(props.provider?.id, {
+                  //           include: networkCurrent || '',
+                  //         });
+                  //       }
+                  //     };
+                  //   }}
+                  // >
+                  //   去新增
+                  // </Button>
+                }
               </span>
             }
           />

+ 24 - 21
src/pages/link/AccessConfig/Detail/components/Protocol/index.tsx

@@ -34,6 +34,8 @@ const Protocol = (props: Props) => {
         encodeQuery({
           ...params,
           sorts: { createTime: 'desc' },
+          'sorts[1].name': 'id',
+          'sorts[1].value': props.data,
         }),
       )
       .then((resp) => {
@@ -142,27 +144,28 @@ const Protocol = (props: Props) => {
             description={
               <span>
                 暂无数据
-                {getButtonPermission('link/Protocol', ['add']) ? (
-                  '请联系管理员进行配置'
-                ) : props.view ? (
-                  ''
-                ) : (
-                  <Button
-                    type="link"
-                    onClick={() => {
-                      const url = getMenuPathByCode(MENUS_CODE[`link/Protocol`]);
-                      const tab: any = window.open(`${origin}/#${url}?save=true`);
-                      tab!.onTabSaveSuccess = (resp: any) => {
-                        if (resp.status === 200) {
-                          setProtocolCurrent(resp.result?.id);
-                          queryProtocolList(props.provider?.id);
-                        }
-                      };
-                    }}
-                  >
-                    去新增
-                  </Button>
-                )}
+                {
+                  getButtonPermission('link/Protocol', ['add'])
+                    ? '请联系管理员进行配置'
+                    : props.view
+                    ? ''
+                    : ''
+                  // <Button
+                  //   type="link"
+                  //   onClick={() => {
+                  //     const url = getMenuPathByCode(MENUS_CODE[`link/Protocol`]);
+                  //     const tab: any = window.open(`${origin}/#${url}?save=true`);
+                  //     tab!.onTabSaveSuccess = (resp: any) => {
+                  //       if (resp.status === 200) {
+                  //         setProtocolCurrent(resp.result?.id);
+                  //         queryProtocolList(props.provider?.id);
+                  //       }
+                  //     };
+                  //   }}
+                  // >
+                  //   去新增
+                  // </Button>
+                }
               </span>
             }
           />

+ 1 - 1
src/pages/media/Device/Channel/Live/index.less

@@ -54,6 +54,6 @@
 
 .media-live-tool {
   display: flex;
-  justify-content: center;
+  // justify-content: center;
   margin-top: 24px;
 }

+ 1 - 0
src/pages/media/Home/deviceModal.tsx

@@ -117,6 +117,7 @@ export default (props: DeviceModalProps) => {
       <SearchComponent<DeviceItem>
         field={columns}
         enableSave={false}
+        model={'simple'}
         onSearch={async (data) => {
           setSearchParam(data);
         }}

+ 78 - 0
src/pages/notice/Config/Detail/index.tsx

@@ -248,6 +248,10 @@ const Detail = observer(() => {
                     max: 64,
                     message: '最多可输入64个字符',
                   },
+                  {
+                    required: true,
+                    message: '请输入corpId',
+                  },
                 ],
               },
               corpSecret: {
@@ -271,6 +275,10 @@ const Detail = observer(() => {
                     max: 64,
                     message: '最多可输入64个字符',
                   },
+                  {
+                    required: true,
+                    message: '请输入corpSecret',
+                  },
                 ],
               },
               appId: {
@@ -294,6 +302,12 @@ const Detail = observer(() => {
                 title: 'AppSecret',
                 'x-component': 'Input',
                 required: true,
+                'x-validator': [
+                  {
+                    required: true,
+                    message: '请输入secret',
+                  },
+                ],
                 'x-decorator': 'FormItem',
                 'x-component-props': {
                   placeholder: '请输入secret',
@@ -342,6 +356,10 @@ const Detail = observer(() => {
                     max: 64,
                     message: '最多可输入64个字符',
                   },
+                  {
+                    required: true,
+                    message: '请输入AppKey',
+                  },
                 ],
               },
               appSecret: {
@@ -357,6 +375,10 @@ const Detail = observer(() => {
                     max: 64,
                     message: '最多可输入64个字符',
                   },
+                  {
+                    required: true,
+                    message: '请输入AppSecret',
+                  },
                 ],
                 'x-reactions': {
                   dependencies: ['provider'],
@@ -375,6 +397,12 @@ const Detail = observer(() => {
                 'x-component-props': {
                   placeholder: '请输入webhook',
                 },
+                'x-validator': [
+                  {
+                    required: true,
+                    message: '请输入webhook',
+                  },
+                ],
                 'x-reactions': {
                   dependencies: ['provider'],
                   fulfill: {
@@ -402,6 +430,12 @@ const Detail = observer(() => {
               regionId: {
                 title: 'RegionId',
                 required: true,
+                'x-validator': [
+                  {
+                    required: true,
+                    message: '请选择regionId',
+                  },
+                ],
                 'x-component-props': {
                   placeholder: '请选择regionId',
                 },
@@ -422,6 +456,10 @@ const Detail = observer(() => {
                     max: 64,
                     message: '最多可输入64个字符',
                   },
+                  {
+                    required: true,
+                    message: '请输入accessKeyId',
+                  },
                 ],
               },
               secret: {
@@ -437,6 +475,10 @@ const Detail = observer(() => {
                     max: 64,
                     message: '最多可输入64个字符',
                   },
+                  {
+                    required: true,
+                    message: '请输入secret',
+                  },
                 ],
               },
             },
@@ -472,6 +514,12 @@ const Detail = observer(() => {
                         width: '180px',
                       },
                     },
+                    'x-validator': [
+                      {
+                        required: true,
+                        message: '请输入服务器地址',
+                      },
+                    ],
                     'x-component': 'FAutoComplete',
                     'x-decorator': 'FormItem',
                     enum: [
@@ -499,6 +547,10 @@ const Detail = observer(() => {
                         max: 65535,
                         message: '请输入1~65535之间的正整数',
                       },
+                      {
+                        required: true,
+                        message: '请输入端口',
+                      },
                     ],
                     'x-component': 'NumberPicker',
                     'x-decorator': 'FormItem',
@@ -545,6 +597,10 @@ const Detail = observer(() => {
                     max: 64,
                     message: '最多可输入64个字符',
                   },
+                  {
+                    required: true,
+                    message: '请输入发件人',
+                  },
                 ],
               },
               username: {
@@ -560,6 +616,10 @@ const Detail = observer(() => {
                     max: 64,
                     message: '最多可输入64个字符',
                   },
+                  {
+                    required: true,
+                    message: '请输入用户名',
+                  },
                 ],
               },
               password: {
@@ -575,6 +635,10 @@ const Detail = observer(() => {
                     max: 64,
                     message: '最多可输入64个字符',
                   },
+                  {
+                    required: true,
+                    message: '请输入密码',
+                  },
                 ],
               },
             },
@@ -597,6 +661,12 @@ const Detail = observer(() => {
                 'x-component-props': {
                   placeholder: '请输入Webhook',
                 },
+                'x-validator': [
+                  {
+                    required: true,
+                    message: '请输入Webhook',
+                  },
+                ],
                 'x-component': 'Input',
                 'x-decorator': 'FormItem',
               },
@@ -627,6 +697,10 @@ const Detail = observer(() => {
                               max: 64,
                               message: '最多可输入64个字符',
                             },
+                            {
+                              required: true,
+                              message: '请输入KEY',
+                            },
                           ],
                         },
                       },
@@ -646,6 +720,10 @@ const Detail = observer(() => {
                               max: 64,
                               message: '最多可输入64个字符',
                             },
+                            {
+                              required: true,
+                              message: '请输入VALUE',
+                            },
                           ],
                         },
                       },

+ 0 - 1
src/pages/notice/Config/index.tsx

@@ -376,7 +376,6 @@ const Config = observer(() => {
                         <ArrowDownOutlined />
                         导出
                       </PermissionButton>
-                      ,
                     </Menu.Item>
                     {(record.provider === 'dingTalkMessage' ||
                       record.provider === 'corpMessage') && (

+ 11 - 0
src/pages/notice/Template/Debug/index.tsx

@@ -42,6 +42,7 @@ const Debug = observer(() => {
 
           onFieldReact('variableDefinitions.*.type', async (field) => {
             const value = (field as Field).value;
+            console.log('value----', value);
 
             const format = field.query('.value').take() as Field;
             const _id = field.query('.id').take() as Field;
@@ -66,6 +67,9 @@ const Debug = observer(() => {
                 case 'number':
                   format.setComponent(NumberPicker, {});
                   break;
+                case 'double':
+                  format.setComponent(NumberPicker, {});
+                  break;
                 case 'file':
                   format.setComponent(FUpload, {
                     type: 'file',
@@ -186,6 +190,13 @@ const Debug = observer(() => {
         default: state?.current?.configId,
         'x-decorator': 'FormItem',
         'x-component': 'Select',
+        'x-component-props': {
+          showSearch: true,
+          allowClear: true,
+          showArrow: true,
+          filterOption: (input: string, option: any) =>
+            option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0,
+        },
         'x-reactions': '{{useAsyncDataSource(getConfig)}}',
       },
       variableDefinitions: {

+ 88 - 0
src/pages/notice/Template/Detail/index.tsx

@@ -649,6 +649,12 @@ const Detail = observer(() => {
           placeholder: '请选择绑定配置',
         },
         required: true,
+        'x-validator': [
+          {
+            required: true,
+            message: '请选择绑定配置',
+          },
+        ],
         'x-decorator-props': {
           tooltip: '使用固定的通知配置来发送此通知模版',
         },
@@ -696,6 +702,10 @@ const Detail = observer(() => {
                         max: 64,
                         message: '最多可输入64个字符',
                       },
+                      {
+                        required: true,
+                        message: '请输入AgentID',
+                      },
                     ],
                   },
                   layout: {
@@ -786,6 +796,12 @@ const Detail = observer(() => {
                           placeholder: '请选择消息模版',
                         },
                         required: true,
+                        'x-validator': [
+                          {
+                            required: true,
+                            message: '请输入AgentID',
+                          },
+                        ],
                         'x-decorator-props': {
                           gridSpan: 1,
                           tooltip: '微信公众号中配置的消息模版',
@@ -934,6 +950,10 @@ const Detail = observer(() => {
                         max: 64,
                         message: '最多可输入64个字符',
                       },
+                      {
+                        required: true,
+                        message: '请输入AgentID',
+                      },
                     ],
                   },
                   layout: {
@@ -1001,6 +1021,12 @@ const Detail = observer(() => {
                     'x-component': 'Select',
                     'x-decorator': 'FormItem',
                     required: true,
+                    'x-validator': [
+                      {
+                        required: true,
+                        message: '请选择消息类型',
+                      },
+                    ],
                     'x-component-props': {
                       placeholder: '请选择消息类型',
                     },
@@ -1026,6 +1052,10 @@ const Detail = observer(() => {
                             max: 64,
                             message: '最多可输入64个字符',
                           },
+                          {
+                            required: true,
+                            message: '请输入标题',
+                          },
                         ],
                       },
                     },
@@ -1054,6 +1084,10 @@ const Detail = observer(() => {
                             max: 64,
                             message: '最多可输入64个字符',
                           },
+                          {
+                            required: true,
+                            message: '请输入标题',
+                          },
                         ],
                       },
                       '{url:picUrl}': {
@@ -1126,6 +1160,12 @@ const Detail = observer(() => {
                     'x-component-props': {
                       placeholder: '请选择类型',
                     },
+                    'x-validator': [
+                      {
+                        required: true,
+                        message: '请选择类型',
+                      },
+                    ],
                     default: 'tts',
                     enum: [
                       { label: '语音通知', value: 'voice' },
@@ -1149,6 +1189,12 @@ const Detail = observer(() => {
                           gridSpan: 1,
                         },
                         required: true,
+                        'x-validator': [
+                          {
+                            required: true,
+                            message: '请输入模版ID',
+                          },
+                        ],
                         'x-component-props': {
                           placeholder: '请输入模版ID',
                         },
@@ -1270,6 +1316,12 @@ const Detail = observer(() => {
                       code: {
                         title: '模版',
                         required: true,
+                        'x-validator': [
+                          {
+                            required: true,
+                            message: '请选择模版',
+                          },
+                        ],
                         'x-component': 'Select',
                         'x-decorator': 'FormItem',
                         'x-decorator-props': {
@@ -1304,6 +1356,12 @@ const Detail = observer(() => {
                   signName: {
                     title: '签名',
                     required: true,
+                    'x-validator': [
+                      {
+                        required: true,
+                        message: '请输入签名',
+                      },
+                    ],
                     'x-component': 'Select',
                     'x-decorator': 'FormItem',
                     'x-decorator-props': {
@@ -1351,6 +1409,10 @@ const Detail = observer(() => {
                     max: 64,
                     message: '最多可输入64个字符',
                   },
+                  {
+                    required: true,
+                    message: '请输入标题',
+                  },
                 ],
               },
               sendTo: {
@@ -1397,6 +1459,12 @@ const Detail = observer(() => {
                         gridSpan: 23,
                       },
                       required: true,
+                      'x-validator': [
+                        {
+                          required: true,
+                          message: '请上传文件或输入文件名称',
+                        },
+                      ],
                       'x-component-props': {
                         type: 'file',
                         display: 'name',
@@ -1521,6 +1589,10 @@ const Detail = observer(() => {
             max: 500,
             message: '最多可输入500个字符',
           },
+          {
+            require: true,
+            message: '请输入模版内容',
+          },
         ],
       },
       variableDefinitions: {
@@ -1574,6 +1646,10 @@ const Detail = observer(() => {
                       max: 64,
                       message: '最多可输入64个字符',
                     },
+                    {
+                      require: true,
+                      message: '请输入名称',
+                    },
                   ],
                 },
               },
@@ -1588,6 +1664,12 @@ const Detail = observer(() => {
                   'x-decorator': 'FormItem',
                   'x-component': 'Select',
                   required: true,
+                  'x-validator': [
+                    {
+                      require: true,
+                      message: '请选择类型',
+                    },
+                  ],
                   enum: [
                     { label: '字符串', value: 'string' },
                     { label: '时间', value: 'date' },
@@ -1601,6 +1683,12 @@ const Detail = observer(() => {
               'x-component': 'ArrayTable.Column',
               'x-component-props': { title: '格式', width: '300px' },
               required: true,
+              'x-validator': [
+                {
+                  require: true,
+                  message: '请输入格式',
+                },
+              ],
               properties: {
                 format: {
                   type: 'string',

+ 2 - 10
src/pages/rule-engine/Alarm/Configuration/index.tsx

@@ -238,11 +238,7 @@ const Configuration = () => {
           key="action"
           style={{ padding: 0 }}
           popConfirm={{
-            title: `${
-              record.state?.value !== 'disabled'
-                ? '禁用告警不会影响关联的场景状态,确定要禁用吗'
-                : '确认启用'
-            }?`,
+            title: `${record.state?.value !== 'disabled' ? '确认禁用' : '确认启用'}?`,
             onConfirm: async () => {
               if (record.state?.value === 'disabled') {
                 await service._enable(record.id);
@@ -375,11 +371,7 @@ const Configuration = () => {
                 isPermission={permission.action}
                 style={{ padding: 0 }}
                 popConfirm={{
-                  title: `${
-                    record.state?.value !== 'disabled'
-                      ? '禁用告警不会影响关联的场景状态,确定要禁用吗'
-                      : '确认启用'
-                  }?`,
+                  title: `${record.state?.value !== 'disabled' ? '确认禁用' : '确认启用'}?`,
                   onConfirm: async () => {
                     if (record.state?.value === 'disabled') {
                       await service._enable(record.id);

+ 8 - 8
src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/TypeModel.tsx

@@ -70,7 +70,7 @@ export default observer((props: Props) => {
         setBuiltInList(filterData);
         if (props.value) {
           const label = optionMap.current.get(props.value);
-          setLabelValue(label?.description);
+          setLabelValue(label?.fullName);
         }
       }
     });
@@ -92,7 +92,6 @@ export default observer((props: Props) => {
 
   useEffect(() => {
     setValue(props.value);
-    // setLabelValue(props.label);
   }, [props.value]);
 
   useEffect(() => {
@@ -212,7 +211,7 @@ export default observer((props: Props) => {
             }}
             onChange={(_: any, timeString: string) => {
               // setDateOpen(false)
-              console.log('timeString', timeString);
+              // console.log('timeString', timeString);
               setValue(timeString);
               setLabelValue(timeString);
               if (props.onChange) {
@@ -254,20 +253,21 @@ export default observer((props: Props) => {
             treeData={builtInList}
             height={300}
             defaultExpandAll
+            defaultSelectedKeys={[props.value]}
             fieldNames={{ title: 'name', key: 'id' }}
             onSelect={(selectedKeys, e) => {
-              // console.log('e.node', e.node);
+              // console.log('e.node', e.node, e);
               if (e.node.metadata) {
                 if (props.onColumns) {
                   props.onColumns(e.node.column);
                 }
               }
               setOpen(false);
-              setLabelValue(e.node.description);
-              DeviceModel.actionName = e.node.description;
+              setLabelValue(e.node.fullName);
+              DeviceModel.actionName = e.node.fullName;
               setValue(selectedKeys[0]);
               if (props.onChange) {
-                props.onChange(selectedKeys[0], source, e.node.description);
+                props.onChange(selectedKeys[0], source, e.node.fullName);
               }
             }}
           />
@@ -323,7 +323,7 @@ export default observer((props: Props) => {
             setObjVisable(false);
           }}
           ok={(param) => {
-            console.log('------', param);
+            // console.log('------', param);
             if (props.onChange) {
               props.onChange(JSON.parse(param));
             }

+ 12 - 7
src/pages/rule-engine/Scene/Save/action/ListItem/FilterCondition.tsx

@@ -188,6 +188,8 @@ export default observer((props: FilterProps) => {
           showLabelKey="fullName"
           isTree={true}
           onChange={(_value, item) => {
+            // console.log('_value-----',_value)
+
             setValue({
               value: undefined,
               source: 'fixed',
@@ -198,11 +200,13 @@ export default observer((props: FilterProps) => {
             const _termTypeOptions: any[] =
               node.termTypes?.map((tItem: any) => ({ title: tItem.name, key: tItem.id })) || [];
             setTtOptions(_termTypeOptions);
-            if (!node.metadata) {
-              columnsRef.current = [node.column];
+            if (node.metadata) {
+              columnsRef.current[0] = node.column;
             } else {
               columnsRef.current = [];
             }
+            console.log('columnsRef.current', columnsRef.current);
+            props.onColumns(columnsRef.current);
             // 默认选中第一个
             let _termTypeValue = undefined;
             if (_termTypeOptions.length) {
@@ -215,6 +219,7 @@ export default observer((props: FilterProps) => {
             }
             ValueRef.current.column = _value!;
             labelCache.current[0] = node.fullName;
+
             valueChange({
               column: _value,
               value: {
@@ -284,7 +289,7 @@ export default observer((props: FilterProps) => {
                 labelCache.current[3] = props.data.type;
 
                 if (v.source === 'upper') {
-                  if (!node.metadata) {
+                  if (node.metadata) {
                     columnsRef.current[1] = node.column;
                   } else {
                     columnsRef.current.splice(1, 1);
@@ -327,7 +332,7 @@ export default observer((props: FilterProps) => {
                 labelCache.current[3] = props.data.type;
 
                 if (v.source === 'upper') {
-                  if (!node.metadata) {
+                  if (node.metadata) {
                     columnsRef.current[2] = node.column;
                   } else {
                     columnsRef.current.splice(2, 1);
@@ -364,15 +369,15 @@ export default observer((props: FilterProps) => {
               setValue({
                 ...v,
               });
-              console.log('node.column-----', node, v);
+              console.log('node.column-----', node);
               if (v.source === 'upper') {
-                if (!node.metadata) {
+                if (node.metadata) {
                   columnsRef.current[1] = node.column;
                 } else {
                   columnsRef.current.splice(1, 1);
                 }
               } else {
-                columnsRef.current = [];
+                columnsRef.current.length = 1;
               }
 
               props.onColumns(columnsRef.current);

+ 4 - 1
src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx

@@ -409,15 +409,18 @@ export default (props: ItemProps) => {
                   label={props.options?.terms?.[index]}
                   actionColumns={props.options?.otherColumns}
                   onColumnsChange={(columns) => {
-                    console.log('-----', columns);
+                    // console.log('columns-----', columns);
 
                     const filterColumns = new Set(flattenDeep(columns)); // 平铺去重
+                    // console.log('filterColumns-----',filterColumns)
+
                     let newColumns = [...filterColumns.values()];
                     if (optionsRef.current?.otherColumns) {
                       newColumns = [...optionsRef.current.otherColumns, ...newColumns];
                     }
                     optionsRef.current['columns'] = newColumns;
                     optionsRef.current['termsColumns'] = columns;
+                    // console.log('optionsRef.current-----',optionsRef.current)
                     props.onUpdate(cacheValueRef.current, optionsRef.current);
                   }}
                   onAddGroup={() => {

+ 17 - 5
src/pages/rule-engine/Scene/Save/components/Buttons/ParamsDropdown.tsx

@@ -25,12 +25,13 @@ export interface ParamsDropdownProps {
   icon?: ReactNode;
   open?: boolean;
   openChange?: (open: boolean) => void;
+  enumList?: any[];
 }
 
 interface MenusProps {
   value: any;
   options?: any[];
-  onChange: (value: any, lb: any, node) => void;
+  onChange: (value: any, lb: any, node: any) => void;
 }
 
 const Menus = (props: MenusProps) => {
@@ -50,7 +51,7 @@ const Menus = (props: MenusProps) => {
         selectedKeys={value ? [value] : undefined}
         items={props.options}
         onClick={({ key, item }: { key: any; item: any }) => {
-          console.log(item.props);
+          // console.log(item.props);
           const _item = props.options?.find((a) => a.value === item.props.value);
           setValue(key);
           if (_item) {
@@ -91,7 +92,7 @@ export default (props: ParamsDropdownProps) => {
       if (config.name && Array.isArray(_v)) {
         _value = _v[config.name];
       }
-
+      // console.log('type---',type,props.enumList)
       switch (type) {
         case 'int':
         case 'long':
@@ -119,10 +120,15 @@ export default (props: ParamsDropdownProps) => {
             />
           );
         case 'enum':
+          const _enums = props.enumList?.map((item) => ({
+            label: item.name,
+            value: item.id,
+            key: item.id,
+          }));
           return (
             <Menus
               value={_value}
-              options={props.options}
+              options={_enums}
               onChange={(v, l) => {
                 onValueChange(v, l);
                 setOpen(false);
@@ -226,6 +232,12 @@ export default (props: ParamsDropdownProps) => {
           });
           break;
         case 'enum':
+          props.enumList?.forEach((item) => {
+            if (item.id === v) {
+              setLabel(item.name);
+            }
+          });
+          break;
         case 'object':
           findLabel(v, props.options || []);
           break;
@@ -236,7 +248,7 @@ export default (props: ParamsDropdownProps) => {
           setLabel(v + '');
       }
     },
-    [props.options, props.BuiltInOptions],
+    [props.options, props.BuiltInOptions, props.enumList],
   );
 
   const initData = useCallback(() => {

+ 13 - 4
src/pages/rule-engine/Scene/Save/terms/paramsItem.tsx

@@ -86,10 +86,11 @@ export const handleOptionsLabel = (data: any, type?: string) => {
       };
       const _value = isObject(v) ? Object.values(v) : [v];
       const typeStr = type ? typeKey[type] : '';
-      if (DoubleFilter.includes(t) && !range) {
+      if (DoubleFilter.includes(t) && _value.length === 2) {
         const str = termsTypeKey[t].replace('_value', _value[0]).replace('_value2', _value[1]);
         return `${c} ${str} ${typeStr} `;
-      } else if (DoubleFilter.includes(t) && !!range) {
+      } else if (DoubleFilter.includes(t) && !!range && _value.length === 1) {
+        console.log(_value, range);
         const str = termsTypeKey[t].replace('_value和_value2', _value[0]);
         return `${c} ${str} ${typeStr} `;
       } else {
@@ -127,6 +128,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
     termType: '',
     value: undefined,
   });
+  const enumRef = useRef<any>([]);
 
   const valueChange = useCallback(
     (_value: any) => {
@@ -156,6 +158,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
             [];
           setTtOptions(_termTypeOptions);
           setValueType(labelOptions.dataType);
+          enumRef.current = labelOptions.options;
           if (labelOptions.metrics) {
             // 指标值
             const _metrics = labelOptions.metrics.map((mItem: any) => ({
@@ -182,7 +185,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
   useEffect(() => {
     setTermType(props.data.termType || '');
     setValue(props.data.value);
-    // console.log(props.data.value,'-----')
+    // console.log('props.data-----', props.data);
     setColumn(props.data.column || '');
     // if(props.data.value?.source === 'metric'){
     //   setIsRange(true)
@@ -255,6 +258,10 @@ const ParamsItem = observer((props: ParamsItemProps) => {
           showLabelKey="fullName"
           isTree={true}
           onChange={(_value, item) => {
+            console.log('item.node---', item.node);
+            if (item.node && item.node.dataType === 'enum') {
+              enumRef.current = item.node.options;
+            }
             setValue({
               value: undefined,
               source: 'manual',
@@ -396,6 +403,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
             placeholder="参数值"
             valueType={valueType}
             value={value}
+            enumList={enumRef.current}
             onChange={(v, lb, item) => {
               console.log('-----', v, lb, item);
               const _value = { ...v };
@@ -412,6 +420,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
               if (!!metricsOptions.length) {
                 if (DoubleFilter.includes(termType) && !isRange) {
                   labelCache.current[2] = { 0: v?.value?.[0], 1: v?.value?.[1] };
+                  labelCache.current.length = 3;
                 } else {
                   labelCache.current[2] = { 0: lb };
                   labelCache.current[4] = 'range';
@@ -420,7 +429,7 @@ const ParamsItem = observer((props: ParamsItemProps) => {
                 labelCache.current[2] = { 0: lb };
               }
               labelCache.current[3] = props.data.type;
-              console.log('labelCache------', [...labelCache.current]);
+              // console.log('labelCache------', [...labelCache.current]);
               props.onLabelChange?.([...labelCache.current]);
               valueEventChange(_value);
             }}

+ 1 - 1
src/pages/rule-engine/Scene/typings.d.ts

@@ -7,7 +7,7 @@ type Action = {
 
 type Trigger = {
   type: string;
-  device: Record<string, unknown>;
+  device: Record<string, any>;
 };
 
 export enum ParallelEnum {

+ 16 - 2
src/pages/system/Apply/Menu/index.tsx

@@ -1,11 +1,14 @@
+import { getMenuPathByCode } from '@/utils/menu';
 import { onlyMessage } from '@/utils/util';
 import { Modal, Tree, Select } from 'antd';
 import { useEffect, useState } from 'react';
+import { useHistory } from 'umi';
 import { service } from '../index';
 
 interface Props {
   close: Function;
   data: any;
+  tag?: string;
 }
 
 const MenuPage = (props: Props) => {
@@ -17,6 +20,7 @@ const MenuPage = (props: Props) => {
   const [half, setHalf] = useState<string[]>([]);
   const [ownerList, setOwenrList] = useState<any>([]);
   const [owner, setOwner] = useState<any>();
+  const history = useHistory();
 
   //获取集成菜单
   const getMenus = async () => {
@@ -73,6 +77,7 @@ const MenuPage = (props: Props) => {
     const res = await service.saveOwnerTree('iot', data.id, datalist);
     if (res?.status === 200) {
       onlyMessage('操作成功');
+      props.close(true);
     }
   };
 
@@ -93,7 +98,8 @@ const MenuPage = (props: Props) => {
   };
 
   useEffect(() => {
-    console.log(data);
+    console.log(data, props.tag);
+
     if (data.id) {
       getOwner();
       getMenus();
@@ -107,9 +113,17 @@ const MenuPage = (props: Props) => {
       title="集成菜单"
       width={600}
       onCancel={() => {
-        props.close();
+        // props.close();
+        if (props.tag === 'add' && data) {
+          props.close();
+          const url = getMenuPathByCode('system/Apply/Save');
+          history.push(`${url}?id=${data.id}`);
+        } else {
+          props.close();
+        }
       }}
       onOk={() => {
+        // props.close(true)
         const items = filterTree(treeData, [...keys, ...half]);
         if (owner) {
           if (items && items.length !== 0) {

+ 14 - 15
src/pages/system/Apply/Save/index.tsx

@@ -46,6 +46,7 @@ const Save = () => {
   const [detail, setDetail] = useState<any>({});
   const accessRef = useRef<any>([]);
   const [type, setType] = useState<any>('internal-standalone');
+  const [tag, setTag] = useState<string>('add');
 
   const provider1 = require('/public/images/apply/provider1.png');
   const provider2 = require('/public/images/apply/provider2.png');
@@ -261,10 +262,10 @@ const Save = () => {
               field.selfErrors = '';
             }
           });
-          onFieldReact('apiServer.appId', (field: any) => {
-            const value = (field as Field).value;
-            console.log(value);
-          });
+          // onFieldReact('apiServer.appId', (field: any) => {
+          //   const value = (field as Field).value;
+          //   console.log(value);
+          // });
         },
       }),
     [id],
@@ -324,7 +325,7 @@ const Save = () => {
           const isPage = data.integrationModes.includes('page');
           if (isPage) {
             setVisiable(true);
-            setDetail(data);
+            setDetail(res.result);
           } else {
             onlyMessage('保存成功');
             const url = getMenuPathByCode('system/Apply');
@@ -1957,23 +1958,16 @@ const Save = () => {
     setView(false);
     const params = new URLSearchParams(location.search);
     const item = params.get('id');
-    // console.log(id);
+    console.log(id);
     if (item) {
       setId(item);
+      setTag('edit');
     }
     if (location && location.state) {
       setView(location.state.view);
     }
   }, [location]);
 
-  useEffect(() => {
-    const item = form.getValuesIn('provider');
-    // console.log(item, form.getState())
-    // setType(localStorage.getItem('type'))
-
-    console.log(item, form.getState());
-  }, []);
-
   return (
     <PageContainer>
       <Card>
@@ -2015,8 +2009,13 @@ const Save = () => {
       {visible && (
         <MenuPage
           data={detail}
-          close={() => {
+          tag={tag}
+          close={(isOk?: any) => {
             setVisiable(false);
+            if (isOk) {
+              const url = getMenuPathByCode('system/Apply');
+              history.push(url);
+            }
           }}
         />
       )}

+ 1 - 1
src/pages/system/DataSource/Management/DataTable.tsx

@@ -30,7 +30,7 @@ const DataTable = (props: Props) => {
     validateId(value) {
       if (!value) return '';
       const reg = new RegExp('^[0-9a-zA-Z_\\\\-]+$');
-      return reg.exec(value) ? '' : 'ID只能由数字、字母、下划线、中划线组成';
+      return reg.exec(value) ? '' : '名称只能由数字、字母、下划线、中划线组成';
     },
   });
 

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

@@ -1481,7 +1481,7 @@ export default [
             showPage: [
               'dashboard',
               'data-collect-channel',
-              'data-collect-opc',
+              // 'data-collect-opc',
               'data-collector',
               'things-collector',
             ],
@@ -1503,7 +1503,7 @@ export default [
             icon: 'icon-rizhifuwu',
             showPage: [
               'data-collect-channel',
-              'data-collect-opc',
+              // 'data-collect-opc',
               'data-collector',
               'things-collector',
             ],
@@ -1634,7 +1634,7 @@ export default [
             icon: 'icon-yingyongguanli',
             showPage: [
               'data-collect-channel',
-              'data-collect-opc',
+              // 'data-collect-opc',
               'data-collector',
               'things-collector',
             ],

+ 17 - 0
src/utils/util.ts

@@ -67,6 +67,23 @@ export const downloadObject = (record: Record<string, any>, fileName: string, fo
   document.body.removeChild(ghostLink);
 };
 
+export const downloadTxT = (record: Record<string, any>, fileName: string, format?: string) => {
+  // 创建隐藏的可下载链接
+  const ghostLink = document.createElement('a');
+  ghostLink.download = `${fileName ? '' : record?.name}${fileName}_${moment(new Date()).format(
+    format || 'YYYY_MM_DD',
+  )}.txt`;
+  ghostLink.style.display = 'none';
+  //字符串内容转成Blob地址
+  const blob = new Blob([JSON.stringify(record)]);
+  ghostLink.href = URL.createObjectURL(blob);
+  //触发点击
+  document.body.appendChild(ghostLink);
+  ghostLink.click();
+  //移除
+  document.body.removeChild(ghostLink);
+};
+
 export const useAsyncDataSource =
   (services: (arg0: Field) => Promise<FieldDataSource>) => (field: Field) => {
     field.loading = true;