wzyyy 3 лет назад
Родитель
Сommit
68a4d2c89f

+ 126 - 0
src/pages/device/Instance/Detail/Modbus/channelList.tsx

@@ -0,0 +1,126 @@
+import { FormItem, Input, ArrayTable, Editable, FormButtonGroup, Submit } from '@formily/antd';
+import { createForm } from '@formily/core';
+import { FormProvider, createSchemaField } from '@formily/react';
+
+const Render = (props: any) => <>{props.value}</>;
+
+const SchemaField = createSchemaField({
+  components: {
+    FormItem,
+    Editable,
+    Input,
+    ArrayTable,
+    Render,
+  },
+});
+
+const form = createForm({
+  initialValues: {
+    array: [{ a2: '111', a1: '1111', a3: '1111' }],
+  },
+});
+
+const schema = {
+  type: 'object',
+  properties: {
+    array: {
+      type: 'array',
+      'x-decorator': 'FormItem',
+      'x-component': 'ArrayTable',
+      'x-component-props': {
+        pagination: { pageSize: 10 },
+        scroll: { x: '100%' },
+      },
+      items: {
+        type: 'object',
+        properties: {
+          column3: {
+            type: 'void',
+            'x-component': 'ArrayTable.Column',
+            'x-component-props': { width: 120, title: '属性' },
+            properties: {
+              a1: {
+                type: 'string',
+                // 'x-decorator': 'Editable',
+                'x-component': 'Render',
+                'x-component-props': {},
+              },
+            },
+          },
+          column4: {
+            type: 'void',
+            'x-component': 'ArrayTable.Column',
+            'x-component-props': { width: 200, title: 'A2' },
+            properties: {
+              a2: {
+                type: 'string',
+                'x-decorator': 'FormItem',
+                'x-component': 'Input',
+              },
+            },
+          },
+          column5: {
+            type: 'void',
+            'x-component': 'ArrayTable.Column',
+            'x-component-props': { width: 200, title: 'A3' },
+            properties: {
+              a3: {
+                type: 'string',
+                'x-decorator': 'FormItem',
+                'x-component': 'Input',
+              },
+            },
+          },
+          column6: {
+            type: 'void',
+            'x-component': 'ArrayTable.Column',
+            'x-component-props': {
+              title: 'Operations',
+              dataIndex: 'operations',
+              width: 100,
+              fixed: 'right',
+            },
+            properties: {
+              item: {
+                type: 'void',
+                'x-component': 'FormItem',
+                properties: {
+                  remove: {
+                    type: 'void',
+                    'x-component': 'ArrayTable.Remove',
+                  },
+                  moveDown: {
+                    type: 'void',
+                    'x-component': 'ArrayTable.MoveDown',
+                  },
+                  moveUp: {
+                    type: 'void',
+                    'x-component': 'ArrayTable.MoveUp',
+                  },
+                },
+              },
+            },
+          },
+        },
+      },
+      properties: {
+        add: {
+          type: 'void',
+          'x-component': 'ArrayTable.Addition',
+          title: '添加条目',
+        },
+      },
+    },
+  },
+};
+
+export default () => {
+  return (
+    <FormProvider form={form}>
+      <SchemaField schema={schema} />
+      <FormButtonGroup>
+        <Submit onSubmit={console.log}>提交</Submit>
+      </FormButtonGroup>
+    </FormProvider>
+  );
+};

+ 70 - 0
src/pages/device/Instance/Detail/Modbus/editTable.tsx

@@ -0,0 +1,70 @@
+import { Card, Input, Switch } from 'antd';
+// import { useEffect } from 'react';
+import './index.less';
+import { useDomFullHeight } from '@/hooks';
+import ChannelList from './channelList';
+
+const Editable = () => {
+  const { minHeight } = useDomFullHeight('.modbus');
+
+  // const data = [
+  //   {
+  //     "id": "1657787131289",
+  //     "title": "",
+  //     "decs": "这个活动真好玩",
+  //     "state": "open",
+  //     "created_at": "2020-05-26T09:42:56Z"
+  //   },
+  //   {
+  //     "id": "1657787131290",
+  //     "title": "活动名称1",
+  //     "decs": "这个活动真好玩",
+  //     "state": "open",
+  //     "created_at": "2020-05-26T09:42:56Z"
+  //   },
+  // ]
+  // useEffect(() => {
+  //   const id = data.map((item) => item.id)
+  //   // setEditableRowKeys(id)
+  // }, [])
+  return (
+    <Card className="modbus" style={{ minHeight }}>
+      <div className="edit-top">
+        <Switch checkedChildren={'正常采集'} unCheckedChildren={'停止采集'} defaultChecked />
+        <Input.Search
+          placeholder="请输入属性"
+          allowClear
+          style={{ width: 190 }}
+          onSearch={(value) => {
+            console.log(value);
+          }}
+        />
+      </div>
+      <div className="edit-table">
+        <ChannelList></ChannelList>
+        {/* <EditableProTable
+          rowKey="id"
+          columns={columns}
+          recordCreatorProps={false}
+          value={data}
+          editable={{
+            type: 'multiple',
+            editableKeys,
+            onChange: setEditableRowKeys,
+            onValuesChange: (record) => {
+              console.log(record)
+            },
+            actionRender: (row, config, defaultDoms) => {
+              return [
+                <Button onClick={() => {
+                  console.log(row, config)
+                }}>启用</Button>
+              ];
+            },
+          }}
+        /> */}
+      </div>
+    </Card>
+  );
+};
+export default Editable;

+ 10 - 0
src/pages/device/Instance/Detail/Modbus/index.less

@@ -0,0 +1,10 @@
+.edit-top {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+.edit-table {
+  .ant-card-body {
+    padding: 12px 0 0 0 !important;
+  }
+}

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

@@ -29,6 +29,7 @@ import Service from '@/pages/device/Instance/service';
 import useLocation from '@/hooks/route/useLocation';
 import { onlyMessage } from '@/utils/util';
 import Parsing from './Parsing';
+// import Editable from './Modbus/editTable';
 
 export const deviceStatus = new Map();
 deviceStatus.set('online', <Badge status="success" text={'在线'} />);
@@ -193,6 +194,7 @@ const InstanceDetail = observer(() => {
           key: 'modbus',
           tab: 'Modbus',
           component: <Modbus />,
+          // component: <Editable />,
         });
       }
       if (response.result.protocol === 'opc-ua') {

+ 274 - 156
src/pages/link/Channel/Modbus/index.tsx

@@ -1,56 +1,96 @@
-import { PageContainer } from '@ant-design/pro-layout';
+import { Badge, Button, Card, Divider, Dropdown, Input, Menu } from 'antd';
+import { useDomFullHeight } from '@/hooks';
+import './index.less';
+import SearchComponent from '@/components/SearchComponent';
 import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { Badge, Card, Col, Row } from 'antd';
-import styles from './index.less';
-import { PermissionButton } from '@/components';
-import { history, useIntl } from 'umi';
+import PermissionButton from '@/components/PermissionButton';
 import {
-  ControlOutlined,
   DeleteOutlined,
   EditOutlined,
+  ExportOutlined,
+  ImportOutlined,
   PlayCircleOutlined,
   PlusOutlined,
   StopOutlined,
 } from '@ant-design/icons';
 import { useRef, useState } from 'react';
-import SearchComponent from '@/components/SearchComponent';
+import { useIntl } from 'umi';
+import ChannelCard from '../channelCard';
+import { PageContainer } from '@ant-design/pro-layout';
 import Service from './service';
-import Save from './Save';
-import { getMenuPathByCode } from '@/utils/menu';
-import { useDomFullHeight } from '@/hooks';
-import { onlyMessage } from '@/utils/util';
-// import NewModbus from '../new'
+import SaveChannel from './saveChannel';
+import SavePoint from './savePoint';
 
-export const service = new Service('modbus/master');
+export const service = new Service('');
 
-const Modbus = () => {
+const NewModbus = () => {
+  const { minHeight } = useDomFullHeight(`.modbus`);
   const intl = useIntl();
   const actionRef = useRef<ActionType>();
-  const [param, setParam] = useState({});
   const { permission } = PermissionButton.usePermission('link/Channel/Modbus');
+  const [param, setParam] = useState({});
+  const [activeKey, setActiveKey] = useState<any>('');
   const [visible, setVisible] = useState<boolean>(false);
-  const [current, setCurrent] = useState<Partial<OpaUa>>({});
-  const { minHeight } = useDomFullHeight(`.modbus`, 24);
-
-  const iconMap = new Map();
-  iconMap.set('1', require('/public/images/channel/1.png'));
-  iconMap.set('2', require('/public/images/channel/2.png'));
-  iconMap.set('3', require('/public/images/channel/3.png'));
-  iconMap.set('4', require('/public/images/channel/4.png'));
+  const [visiblePoint, setVisiblePoint] = useState<boolean>(false);
+  const [current, setCurrent] = useState<any>({});
+  const [pointDetail, setPointDetail] = useState<any>({});
+  const data = [
+    {
+      id: 1,
+      status: 'connect',
+      state: {
+        text: '正常',
+        value: 'enabled',
+      },
+    },
+    {
+      id: 2,
+      status: 'disconnect',
+      state: {
+        text: '禁用',
+        value: 'disabled',
+      },
+    },
+  ];
 
-  const columns: ProColumns<OpaUa>[] = [
+  const columns: ProColumns<any>[] = [
     {
-      title: '通道名称',
+      title: '名称',
       dataIndex: 'name',
       ellipsis: true,
+      width: 200,
       fixed: 'left',
     },
     {
-      title: 'IP',
+      title: '功能码',
       dataIndex: 'host',
     },
     {
-      title: '端口',
+      title: '从站ID',
+      dataIndex: 'port',
+      search: false,
+      valueType: 'digit',
+    },
+    {
+      title: '寄存器数量',
+      dataIndex: 'port',
+      search: false,
+      valueType: 'digit',
+    },
+    {
+      title: '地址',
+      dataIndex: 'port',
+      search: false,
+      valueType: 'digit',
+    },
+    {
+      title: '当前数据',
+      dataIndex: 'port',
+      search: false,
+      valueType: 'digit',
+    },
+    {
+      title: '采集状态',
       dataIndex: 'port',
       search: false,
       valueType: 'digit',
@@ -81,15 +121,15 @@ const Modbus = () => {
       title: '操作',
       valueType: 'option',
       align: 'center',
-      width: 200,
+      width: 120,
       fixed: 'right',
       render: (text, record) => [
         <PermissionButton
           isPermission={permission.update}
           key="edit"
           onClick={() => {
-            setVisible(true);
-            setCurrent(record);
+            // setVisible(true);
+            // setCurrent(record);
           }}
           type={'link'}
           style={{ padding: 0 }}
@@ -114,24 +154,24 @@ const Modbus = () => {
               defaultMessage: '确认禁用?',
             }),
             onConfirm: async () => {
-              if (record.state.value === 'disabled') {
-                await service.edit({
-                  ...record,
-                  state: 'enabled',
-                });
-              } else {
-                await service.edit({
-                  ...record,
-                  state: 'disabled',
-                });
-              }
-              onlyMessage(
-                intl.formatMessage({
-                  id: 'pages.data.option.success',
-                  defaultMessage: '操作成功!',
-                }),
-              );
-              actionRef.current?.reload();
+              //   if (record.state.value === 'disabled') {
+              //     await service.edit({
+              //       ...record,
+              //       state: 'enabled',
+              //     });
+              //   } else {
+              //     await service.edit({
+              //       ...record,
+              //       state: 'disabled',
+              //     });
+              //   }
+              //   onlyMessage(
+              //     intl.formatMessage({
+              //       id: 'pages.data.option.success',
+              //       defaultMessage: '操作成功!',
+              //     }),
+              //   );
+              //   actionRef.current?.reload();
             },
           }}
           isPermission={permission.action}
@@ -145,20 +185,6 @@ const Modbus = () => {
           {record.state.value !== 'disabled' ? <StopOutlined /> : <PlayCircleOutlined />}
         </PermissionButton>,
         <PermissionButton
-          isPermission={permission.view}
-          style={{ padding: 0 }}
-          key="link"
-          type="link"
-          tooltip={{
-            title: '数据点绑定',
-          }}
-          onClick={() => {
-            history.push(`${getMenuPathByCode('link/Channel/Modbus/Access')}?id=${record.id}`);
-          }}
-        >
-          <ControlOutlined />
-        </PermissionButton>,
-        <PermissionButton
           isPermission={permission.delete}
           style={{ padding: 0 }}
           disabled={record.state.value === 'enabled'}
@@ -166,16 +192,16 @@ const Modbus = () => {
             title: '确认删除',
             disabled: record.state.value === 'enabled',
             onConfirm: async () => {
-              const resp: any = await service.remove(record.id);
-              if (resp.status === 200) {
-                onlyMessage(
-                  intl.formatMessage({
-                    id: 'pages.data.option.success',
-                    defaultMessage: '操作成功!',
-                  }),
-                );
-                actionRef.current?.reload();
-              }
+              //   const resp: any = await service.remove(record.id);
+              //   if (resp.status === 200) {
+              //     onlyMessage(
+              //       intl.formatMessage({
+              //         id: 'pages.data.option.success',
+              //         defaultMessage: '操作成功!',
+              //       }),
+              //     );
+              //     actionRef.current?.reload();
+              //   }
             },
           }}
           key="delete"
@@ -187,93 +213,176 @@ const Modbus = () => {
     },
   ];
 
-  const topCard = [
-    {
-      numeber: '1',
-      title: 'Modbus通道',
-      text: '配置Modbus通道',
-    },
-    {
-      numeber: '2',
-      title: '设备接入网关',
-      text: '创建Modbus设备接入网关',
-    },
-    {
-      numeber: '3',
-      title: '创建产品',
-      text: '创建产品,并选择接入方式为Modbus',
-    },
-    {
-      numeber: '4',
-      title: '添加设备',
-      text: '添加设备,单独为每一个设备进行数据点绑定',
-    },
-  ];
+  const menu = (
+    <Menu>
+      <Menu.Item key="1">
+        <PermissionButton
+          isPermission={permission.export}
+          icon={<ExportOutlined />}
+          type="default"
+          onClick={() => {
+            // setExportVisible(true);
+          }}
+        >
+          批量导出设备
+        </PermissionButton>
+      </Menu.Item>
+      <Menu.Item key="2">
+        <PermissionButton
+          isPermission={permission.import}
+          icon={<ImportOutlined />}
+          onClick={() => {
+            // setImportVisible(true);
+          }}
+        >
+          批量导入设备
+        </PermissionButton>
+      </Menu.Item>
+    </Menu>
+  );
+
   return (
     <PageContainer>
-      {/* <NewModbus/> */}
-      <Card style={{ marginBottom: 10 }}>
-        <Row gutter={[24, 24]}>
-          {topCard.map((item) => (
-            <Col span={6} key={item.numeber}>
-              <Card>
-                <div className={styles.topCard}>
-                  <div>
-                    <img src={iconMap.get(item.numeber)} />
-                  </div>
-                  <div className={styles.text}>
-                    <p className={styles.p1}>{item.title}</p>
-                    <p className={styles.p2}>{item.text}</p>
-                  </div>
-                </div>
-              </Card>
-            </Col>
-          ))}
-        </Row>
+      <Card className="modbus" style={{ minHeight }}>
+        <div className="item">
+          <div className="item-left">
+            <div style={{ width: 220 }}>
+              <Input.Search
+                placeholder="请输入名称"
+                allowClear
+                onSearch={(value) => {
+                  console.log(value);
+                }}
+              />
+              <PermissionButton
+                onClick={() => {
+                  setVisible(true);
+                  setCurrent({});
+                }}
+                isPermission={permission.add}
+                key="add"
+                icon={<PlusOutlined />}
+                type="default"
+                style={{ width: '100%', marginTop: 16 }}
+              >
+                新增
+              </PermissionButton>
+              <div className="item-left-list">
+                {data.map((item) => (
+                  <ChannelCard
+                    active={activeKey === item.id}
+                    data={item}
+                    onClick={() => {
+                      setActiveKey(item.id);
+                    }}
+                    actions={
+                      <>
+                        <PermissionButton
+                          isPermission={permission.update}
+                          key="edit"
+                          onClick={() => {
+                            // setVisible(true);
+                            // setCurrent(record);
+                          }}
+                          type={'link'}
+                          style={{ padding: 0 }}
+                        >
+                          <EditOutlined />
+                          编辑
+                        </PermissionButton>
+                        <Divider type="vertical" />
+                        <PermissionButton
+                          isPermission={permission.update}
+                          key="enbale"
+                          type={'link'}
+                          style={{ padding: 0 }}
+                          popConfirm={{
+                            title: intl.formatMessage({
+                              id: `pages.data.option.${
+                                item.state.value !== 'disabled' ? 'disabled' : 'enabled'
+                              }.tips`,
+                              defaultMessage: '确认禁用?',
+                            }),
+                            onConfirm: async () => {},
+                          }}
+                        >
+                          {item.state.value === 'enabled' ? (
+                            <StopOutlined />
+                          ) : (
+                            <PlayCircleOutlined />
+                          )}
+                          {item.state.value === 'enabled' ? '禁用' : '启用'}
+                        </PermissionButton>
+                        <Divider type="vertical" />
+                        <PermissionButton
+                          isPermission={permission.delete}
+                          style={{ padding: 0 }}
+                          disabled={item.state.value === 'enabled'}
+                          popConfirm={{
+                            title: '确认删除',
+                            disabled: item.state.value === 'enabled',
+                            onConfirm: async () => {},
+                          }}
+                          key="delete"
+                          type="link"
+                        >
+                          <DeleteOutlined />
+                        </PermissionButton>
+                      </>
+                    }
+                  />
+                ))}
+              </div>
+            </div>
+          </div>
+          <div className="item-right">
+            <SearchComponent<any>
+              field={columns}
+              target="modbus"
+              onSearch={(value) => {
+                actionRef.current?.reset?.();
+                setParam(value);
+              }}
+            />
+            <ProTable
+              actionRef={actionRef}
+              params={param}
+              columns={columns}
+              rowKey="id"
+              // scroll={{ x: 1000 }}
+              search={false}
+              headerTitle={
+                <>
+                  <PermissionButton
+                    onClick={() => {
+                      setPointDetail({});
+                      setVisiblePoint(true);
+                    }}
+                    isPermission={permission.add}
+                    key="add"
+                    icon={<PlusOutlined />}
+                    type="primary"
+                    style={{ marginRight: 10 }}
+                  >
+                    {intl.formatMessage({
+                      id: 'pages.data.option.add',
+                      defaultMessage: '新增',
+                    })}
+                  </PermissionButton>
+                  <Dropdown key={'more'} overlay={menu} placement="bottom">
+                    <Button>批量操作</Button>
+                  </Dropdown>
+                </>
+              }
+              // request={async (params) =>
+              //     service.query({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
+              // }
+            />
+          </div>
+        </div>
       </Card>
-
-      <SearchComponent<any>
-        field={columns}
-        target="opcua"
-        onSearch={(data) => {
-          // 重置分页数据
-          actionRef.current?.reset?.();
-          setParam(data);
-        }}
-      />
-      <ProTable<OpaUa>
-        actionRef={actionRef}
-        params={param}
-        columns={columns}
-        rowKey="id"
-        scroll={{ x: 1366 }}
-        search={false}
-        tableClassName={'modbus'}
-        tableStyle={{ minHeight }}
-        headerTitle={
-          <PermissionButton
-            onClick={() => {
-              // setMode('add');
-              setVisible(true);
-              setCurrent({});
-            }}
-            isPermission={permission.add}
-            key="add"
-            icon={<PlusOutlined />}
-            type="primary"
-          >
-            {intl.formatMessage({
-              id: 'pages.data.option.add',
-              defaultMessage: '新增',
-            })}
-          </PermissionButton>
-        }
-        request={async (params) =>
-          service.query({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
-        }
-      />
       {visible && (
-        <Save
+        <SaveChannel
           data={current}
           close={() => {
             setVisible(false);
@@ -281,7 +390,16 @@ const Modbus = () => {
           }}
         />
       )}
+      {visiblePoint && (
+        <SavePoint
+          data={pointDetail}
+          close={() => {
+            setVisiblePoint(false);
+            actionRef.current?.reload();
+          }}
+        />
+      )}
     </PageContainer>
   );
 };
-export default Modbus;
+export default NewModbus;

+ 152 - 0
src/pages/link/Channel/Modbus/saveChannel.tsx

@@ -0,0 +1,152 @@
+import { createForm } from '@formily/core';
+import { createSchemaField } from '@formily/react';
+import { Form, FormGrid, FormItem, Input, NumberPicker, Select } from '@formily/antd';
+import type { ISchema } from '@formily/json-schema';
+// import { service } from '@/pages/link/Channel/Modbus';
+import { Modal } from '@/components';
+import { useEffect } from 'react';
+// import { onlyMessage } from '@/utils/util';
+
+interface Props {
+  data: any;
+  close: () => void;
+  device?: any;
+}
+
+const SaveChannel = (props: Props) => {
+  const form = createForm({
+    validateFirst: true,
+    initialValues: props.data,
+  });
+
+  const SchemaField = createSchemaField({
+    components: {
+      FormItem,
+      Input,
+      Select,
+      FormGrid,
+      NumberPicker,
+    },
+  });
+
+  const schema: ISchema = {
+    type: 'object',
+    properties: {
+      layout: {
+        type: 'void',
+        'x-decorator': 'FormGrid',
+        'x-decorator-props': {
+          maxColumns: 2,
+          minColumns: 2,
+          columnGap: 24,
+        },
+        properties: {
+          name: {
+            title: '名称',
+            type: 'string',
+            'x-decorator': 'FormItem',
+            'x-component': 'Input',
+            'x-decorator-props': {
+              gridSpan: 2,
+            },
+            'x-component-props': {
+              placeholder: '请输入名称',
+            },
+            name: 'name',
+            'x-validator': [
+              {
+                max: 64,
+                message: '最多可输入64个字符',
+              },
+              {
+                required: true,
+                message: '请输入名称',
+              },
+            ],
+          },
+          host: {
+            title: 'IP',
+            'x-decorator-props': {
+              gridSpan: 2,
+            },
+            type: 'string',
+            'x-decorator': 'FormItem',
+            'x-component': 'Input',
+            'x-component-props': {
+              placeholder: '请输入IP',
+            },
+            'x-validator': ['ipv4'],
+            name: 'host',
+            required: true,
+          },
+          port: {
+            title: '端口',
+            'x-decorator-props': {
+              gridSpan: 2,
+            },
+            type: 'string',
+            'x-decorator': 'FormItem',
+            'x-component': 'NumberPicker',
+            'x-component-props': {
+              placeholder: '请输入端口',
+            },
+            default: 502,
+            'x-validator': [
+              {
+                min: 1,
+                max: 65535,
+                message: '请输入1~65535之间的正整数',
+              },
+            ],
+            name: 'host',
+            required: true,
+          },
+          description: {
+            title: '说明',
+            'x-decorator': 'FormItem',
+            'x-component': 'Input.TextArea',
+            'x-component-props': {
+              rows: 5,
+              placeholder: '请输入说明',
+            },
+            'x-decorator-props': {
+              gridSpan: 2,
+            },
+            'x-validator': [
+              {
+                max: 200,
+                message: '最多可输入200个字符',
+              },
+            ],
+          },
+        },
+      },
+    },
+  };
+
+  const save = async () => {
+    const value = await form.submit<any>();
+    console.log(value);
+  };
+
+  useEffect(() => {
+    console.log(props.data.id);
+  }, []);
+  return (
+    <Modal
+      title={props.data.id ? '编辑通道' : '新增通道'}
+      maskClosable={false}
+      visible
+      onCancel={props.close}
+      onOk={save}
+      width="35vw"
+      permissionCode={'link/Channel/Modbus'}
+      permission={['add', 'edit']}
+    >
+      <Form form={form} layout="vertical">
+        <SchemaField schema={schema} />
+      </Form>
+    </Modal>
+  );
+};
+export default SaveChannel;

+ 159 - 0
src/pages/link/Channel/Modbus/savePoint.tsx

@@ -0,0 +1,159 @@
+import { Col, Form, Input, InputNumber, Modal, Row, Select } from 'antd';
+// import { useEffect, useState } from 'react';
+// import { service } from '@/pages/link/Channel/Modbus';
+// import { onlyMessage } from '@/utils/util';
+
+interface Props {
+  data: any;
+  close: Function;
+}
+
+const SavePoint = (props: Props) => {
+  const [form] = Form.useForm();
+
+  const handleSave = async () => {
+    const formData = await form.validateFields();
+    console.log(formData);
+  };
+
+  return (
+    <Modal
+      title={props.data.id ? '编辑点位' : '新增点位'}
+      visible
+      width="40vw"
+      destroyOnClose
+      onOk={handleSave}
+      onCancel={() => {
+        props.close();
+      }}
+    >
+      <Form
+        form={form}
+        layout="vertical"
+        // initialValues={{
+        //     ...props.data,
+        //     codecConfig: {
+        //         ...props.data?.codecConfig,
+        //         readIndex: props.data?.codecConfig?.readIndex || 0,
+        //         scaleFactor: props.data?.codecConfig?.scaleFactor || 1,
+        //         revertBytes: props.data?.codecConfig?.revertBytes || false,
+        //     },
+        // }}
+      >
+        <Row gutter={[24, 24]}>
+          <Col span={24}>
+            <Form.Item
+              label="名称"
+              name="name"
+              required
+              rules={[{ required: true, message: '名称必填' }]}
+            >
+              <Input placeholder="请输入名称" />
+            </Form.Item>
+          </Col>
+        </Row>
+        <Row gutter={[24, 24]}>
+          <Col span={12}>
+            <Form.Item
+              label="功能码"
+              name="function"
+              required
+              rules={[{ required: true, message: '功能码必选' }]}
+            >
+              <Select placeholder="请选择">
+                <Select.Option value={'Coils'}>线圈寄存器</Select.Option>
+                <Select.Option value={'HoldingRegisters'}>保存寄存器</Select.Option>
+                <Select.Option value={'InputRegisters'}>输入寄存器</Select.Option>
+              </Select>
+            </Form.Item>
+          </Col>
+          <Col span={12}>
+            <Form.Item
+              label="从站ID"
+              name="unitId"
+              required
+              rules={[
+                { required: true, message: '从站ID' },
+                ({}) => ({
+                  validator(_, value) {
+                    if (value !== 0 || /(^[1-9]\d*$)/.test(value)) {
+                      return Promise.resolve();
+                    }
+                    return Promise.reject(new Error('请输入非0正整数'));
+                  },
+                }),
+              ]}
+            >
+              <InputNumber style={{ width: '100%' }} placeholder="请输入" min={0} />
+            </Form.Item>
+          </Col>
+        </Row>
+        <Row gutter={[24, 24]}>
+          <Col span={24}>
+            <Form.Item
+              label="寄存器数量"
+              name="quantity"
+              rules={[
+                { required: true, message: '请输入寄存器数量' },
+                ({}) => ({
+                  validator(_, value) {
+                    if (/(^[0-9]\d*$)/.test(value)) {
+                      return Promise.resolve();
+                    }
+                    return Promise.reject(new Error('请输入正整数'));
+                  },
+                }),
+              ]}
+            >
+              <InputNumber style={{ width: '100%' }} placeholder="请输入" min={1} />
+            </Form.Item>
+          </Col>
+        </Row>
+        <Row gutter={[24, 24]}>
+          <Col span={24}>
+            <Form.Item
+              label="地址"
+              name="address"
+              tooltip="要获取的对象地址"
+              rules={[
+                { required: true, message: '请输入读取长度' },
+                ({}) => ({
+                  validator(_, value) {
+                    if (value > 1 && value < 255) {
+                      return Promise.resolve();
+                    }
+                    return Promise.reject(new Error('请输入1~255之间的数字'));
+                  },
+                }),
+              ]}
+            >
+              <InputNumber style={{ width: '100%' }} placeholder="请输入" min={1} />
+            </Form.Item>
+          </Col>
+        </Row>
+        <Row gutter={[24, 24]}>
+          <Col span={24}>
+            <Form.Item
+              label="采集频率"
+              name="interval"
+              tooltip="若不填写表示不定时拉取数据"
+              rules={[
+                ({}) => ({
+                  validator(_, value) {
+                    if (value !== 0 || /(^[1-9]\d*$)/.test(value)) {
+                      return Promise.resolve();
+                    }
+                    return Promise.reject(new Error('请输入正整数'));
+                  },
+                }),
+              ]}
+            >
+              <InputNumber style={{ width: '100%' }} placeholder="请输入" addonAfter={<>ms</>} />
+            </Form.Item>
+          </Col>
+        </Row>
+      </Form>
+    </Modal>
+  );
+};
+export default SavePoint;

+ 356 - 368
src/pages/link/Channel/new.tsx

@@ -1,383 +1,371 @@
-import { Button, Card, Divider, Dropdown, Input, Menu } from 'antd';
+import { Badge, Button, Card, Divider, Dropdown, Input, Menu } from 'antd';
 import { useDomFullHeight } from '@/hooks';
-import './index.less'
+import './index.less';
 import SearchComponent from '@/components/SearchComponent';
 import ProTable, { ActionType, ProColumns } from '@jetlinks/pro-table';
 import PermissionButton from '@/components/PermissionButton';
-import { DeleteOutlined, EditOutlined, ExportOutlined, ImportOutlined, PlayCircleOutlined, PlusOutlined, StopOutlined } from '@ant-design/icons';
+import {
+  DeleteOutlined,
+  EditOutlined,
+  ExportOutlined,
+  ImportOutlined,
+  PlayCircleOutlined,
+  PlusOutlined,
+  StopOutlined,
+} from '@ant-design/icons';
 import { useRef, useState } from 'react';
 import { useIntl } from 'umi';
-import ChannelCard from './channelCard'
+import ChannelCard from './channelCard';
 
 const NewModbus = () => {
-    const { minHeight } = useDomFullHeight(`.modbus`);
-    const intl = useIntl();
-    const actionRef = useRef<ActionType>();
-    const { permission } = PermissionButton.usePermission('link/Channel/Modbus');
-    const [param, setParam] = useState({});
-    const [activeKey, setActiveKey] = useState<any>('')
-    const data = [
-        {
-            id: 1,
-            status: 'connect',
-            state: {
-                text: '正常',
-                value: 'enabled'
-            }
-        },
-        {
-            id: 2,
-            status: 'disconnect',
-            state: {
-                text: '禁用',
-                value: 'disabled'
-            }
-        },
-    ]
+  const { minHeight } = useDomFullHeight(`.modbus`);
+  const intl = useIntl();
+  const actionRef = useRef<ActionType>();
+  const { permission } = PermissionButton.usePermission('link/Channel/Modbus');
+  const [param, setParam] = useState({});
+  const [activeKey, setActiveKey] = useState<any>('');
+  const data = [
+    {
+      id: 1,
+      status: 'connect',
+      state: {
+        text: '正常',
+        value: 'enabled',
+      },
+    },
+    {
+      id: 2,
+      status: 'disconnect',
+      state: {
+        text: '禁用',
+        value: 'disabled',
+      },
+    },
+  ];
 
-    const columns: ProColumns<any>[] = [
-        {
-            title: '名称',
-            dataIndex: 'name',
-            ellipsis: true,
-            fixed: 'left',
-        },
-        {
-            title: '功能码',
-            dataIndex: 'host',
-        },
-        {
-            title: '从站ID',
-            dataIndex: 'port',
-            search: false,
-            valueType: 'digit',
-        },
-        {
-            title: '寄存器数量',
-            dataIndex: 'port',
-            search: false,
-            valueType: 'digit',
+  const columns: ProColumns<any>[] = [
+    {
+      title: '名称',
+      dataIndex: 'name',
+      ellipsis: true,
+      width: 200,
+      fixed: 'left',
+    },
+    {
+      title: '功能码',
+      dataIndex: 'host',
+    },
+    {
+      title: '从站ID',
+      dataIndex: 'port',
+      search: false,
+      valueType: 'digit',
+    },
+    {
+      title: '寄存器数量',
+      dataIndex: 'port',
+      search: false,
+      valueType: 'digit',
+    },
+    {
+      title: '地址',
+      dataIndex: 'port',
+      search: false,
+      valueType: 'digit',
+    },
+    {
+      title: '当前数据',
+      dataIndex: 'port',
+      search: false,
+      valueType: 'digit',
+    },
+    {
+      title: '采集状态',
+      dataIndex: 'port',
+      search: false,
+      valueType: 'digit',
+    },
+    {
+      title: '状态',
+      dataIndex: 'state',
+      renderText: (state) => (
+        <Badge text={state?.text} status={state?.value === 'disabled' ? 'error' : 'success'} />
+      ),
+      valueType: 'select',
+      valueEnum: {
+        disabled: {
+          text: intl.formatMessage({
+            id: 'pages.data.option.disabled',
+            defaultMessage: '禁用',
+          }),
+          status: 'disabled',
         },
-        {
-            title: '地址',
-            dataIndex: 'port',
-            search: false,
-            valueType: 'digit',
+        enabled: {
+          text: '正常',
+          status: 'enabled',
         },
-        {
-            title: '当前数据',
-            dataIndex: 'port',
-            search: false,
-            valueType: 'digit',
-        },
-        {
-            title: '采集状态',
-            dataIndex: 'port',
-            search: false,
-            valueType: 'digit',
-        },
-        {
-            title: '状态',
-            dataIndex: 'port',
-            search: false,
-            valueType: 'digit',
-        },
-        // {
-        //   title: '状态',
-        //   dataIndex: 'state',
-        //   renderText: (state) => (
-        //     <Badge text={state?.text} status={state?.value === 'disabled' ? 'error' : 'success'} />
-        //   ),
-        //   valueType: 'select',
-        //   valueEnum: {
-        //     disabled: {
-        //       text: intl.formatMessage({
-        //         id: 'pages.data.option.disabled',
-        //         defaultMessage: '禁用',
-        //       }),
-        //       status: 'disabled',
-        //     },
-        //     enabled: {
-        //       text: '正常',
-        //       status: 'enabled',
-        //     },
-        //   },
-        //   filterMultiple: false,
-        // },
-        // {
-        //   title: '操作',
-        //   valueType: 'option',
-        //   align: 'center',
-        //   width: 200,
-        //   fixed: 'right',
-        //   render: (text, record) => [
-        //     <PermissionButton
-        //       isPermission={permission.update}
-        //       key="edit"
-        //       onClick={() => {
-        //         setVisible(true);
-        //         setCurrent(record);
-        //       }}
-        //       type={'link'}
-        //       style={{ padding: 0 }}
-        //       tooltip={{
-        //         title: intl.formatMessage({
-        //           id: 'pages.data.option.edit',
-        //           defaultMessage: '编辑',
-        //         }),
-        //       }}
-        //     >
-        //       <EditOutlined />
-        //     </PermissionButton>,
-        //     <PermissionButton
-        //       type="link"
-        //       key={'action'}
-        //       style={{ padding: 0 }}
-        //       popConfirm={{
-        //         title: intl.formatMessage({
-        //           id: `pages.data.option.${
-        //             record.state.value !== 'disabled' ? 'disabled' : 'enabled'
-        //           }.tips`,
-        //           defaultMessage: '确认禁用?',
-        //         }),
-        //         onConfirm: async () => {
-        //           if (record.state.value === 'disabled') {
-        //             await service.edit({
-        //               ...record,
-        //               state: 'enabled',
-        //             });
-        //           } else {
-        //             await service.edit({
-        //               ...record,
-        //               state: 'disabled',
-        //             });
-        //           }
-        //           onlyMessage(
-        //             intl.formatMessage({
-        //               id: 'pages.data.option.success',
-        //               defaultMessage: '操作成功!',
-        //             }),
-        //           );
-        //           actionRef.current?.reload();
-        //         },
-        //       }}
-        //       isPermission={permission.action}
-        //       tooltip={{
-        //         title: intl.formatMessage({
-        //           id: `pages.data.option.${record.state.value !== 'disabled' ? 'disabled' : 'enabled'}`,
-        //           defaultMessage: record.state.value !== 'disabled' ? '禁用' : '启用',
-        //         }),
-        //       }}
-        //     >
-        //       {record.state.value !== 'disabled' ? <StopOutlined /> : <PlayCircleOutlined />}
-        //     </PermissionButton>,
-        //     <PermissionButton
-        //       isPermission={permission.view}
-        //       style={{ padding: 0 }}
-        //       key="link"
-        //       type="link"
-        //       tooltip={{
-        //         title: '数据点绑定',
-        //       }}
-        //       onClick={() => {
-        //         history.push(`${getMenuPathByCode('link/Channel/Modbus/Access')}?id=${record.id}`);
-        //       }}
-        //     >
-        //       <ControlOutlined />
-        //     </PermissionButton>,
-        //     <PermissionButton
-        //       isPermission={permission.delete}
-        //       style={{ padding: 0 }}
-        //       disabled={record.state.value === 'enabled'}
-        //       popConfirm={{
-        //         title: '确认删除',
-        //         disabled: record.state.value === 'enabled',
-        //         onConfirm: async () => {
-        //           const resp: any = await service.remove(record.id);
-        //           if (resp.status === 200) {
-        //             onlyMessage(
-        //               intl.formatMessage({
-        //                 id: 'pages.data.option.success',
-        //                 defaultMessage: '操作成功!',
-        //               }),
-        //             );
-        //             actionRef.current?.reload();
-        //           }
-        //         },
-        //       }}
-        //       key="delete"
-        //       type="link"
-        //     >
-        //       <DeleteOutlined />
-        //     </PermissionButton>,
-        //   ],
-        // },
-    ];
+      },
+      filterMultiple: false,
+    },
+    {
+      title: '操作',
+      valueType: 'option',
+      align: 'center',
+      width: 120,
+      fixed: 'right',
+      render: (text, record) => [
+        <PermissionButton
+          isPermission={permission.update}
+          key="edit"
+          onClick={() => {
+            // setVisible(true);
+            // setCurrent(record);
+          }}
+          type={'link'}
+          style={{ padding: 0 }}
+          tooltip={{
+            title: intl.formatMessage({
+              id: 'pages.data.option.edit',
+              defaultMessage: '编辑',
+            }),
+          }}
+        >
+          <EditOutlined />
+        </PermissionButton>,
+        <PermissionButton
+          type="link"
+          key={'action'}
+          style={{ padding: 0 }}
+          popConfirm={{
+            title: intl.formatMessage({
+              id: `pages.data.option.${
+                record.state.value !== 'disabled' ? 'disabled' : 'enabled'
+              }.tips`,
+              defaultMessage: '确认禁用?',
+            }),
+            onConfirm: async () => {
+              //   if (record.state.value === 'disabled') {
+              //     await service.edit({
+              //       ...record,
+              //       state: 'enabled',
+              //     });
+              //   } else {
+              //     await service.edit({
+              //       ...record,
+              //       state: 'disabled',
+              //     });
+              //   }
+              //   onlyMessage(
+              //     intl.formatMessage({
+              //       id: 'pages.data.option.success',
+              //       defaultMessage: '操作成功!',
+              //     }),
+              //   );
+              //   actionRef.current?.reload();
+            },
+          }}
+          isPermission={permission.action}
+          tooltip={{
+            title: intl.formatMessage({
+              id: `pages.data.option.${record.state.value !== 'disabled' ? 'disabled' : 'enabled'}`,
+              defaultMessage: record.state.value !== 'disabled' ? '禁用' : '启用',
+            }),
+          }}
+        >
+          {record.state.value !== 'disabled' ? <StopOutlined /> : <PlayCircleOutlined />}
+        </PermissionButton>,
+        <PermissionButton
+          isPermission={permission.delete}
+          style={{ padding: 0 }}
+          disabled={record.state.value === 'enabled'}
+          popConfirm={{
+            title: '确认删除',
+            disabled: record.state.value === 'enabled',
+            onConfirm: async () => {
+              //   const resp: any = await service.remove(record.id);
+              //   if (resp.status === 200) {
+              //     onlyMessage(
+              //       intl.formatMessage({
+              //         id: 'pages.data.option.success',
+              //         defaultMessage: '操作成功!',
+              //       }),
+              //     );
+              //     actionRef.current?.reload();
+              //   }
+            },
+          }}
+          key="delete"
+          type="link"
+        >
+          <DeleteOutlined />
+        </PermissionButton>,
+      ],
+    },
+  ];
 
-    const menu = (
-        <Menu>
-            <Menu.Item key="1">
-                <PermissionButton
-                    isPermission={permission.export}
-                    icon={<ExportOutlined />}
-                    type="default"
-                    onClick={() => {
-                        // setExportVisible(true);
-                    }}
-                >
-                    批量导出设备
-                </PermissionButton>
-            </Menu.Item>
-            <Menu.Item key="2">
-                <PermissionButton
-                    isPermission={permission.import}
-                    icon={<ImportOutlined />}
-                    onClick={() => {
-                        // setImportVisible(true);
-                    }}
-                >
-                    批量导入设备
-                </PermissionButton>
-            </Menu.Item>
-        </Menu>
-    );
-
-    return (
-        <Card className='modbus' style={{ minHeight }}>
-            <div className='item'>
-                <div className='item-left'>
-                    <div style={{ width: 220 }}>
-                        <Input.Search
-                            placeholder="请输入名称"
-                            allowClear
-                            onSearch={(value) => {
-                                console.log(value)
-                            }}
-                        />
-                        <PermissionButton
-                            onClick={() => {
-                                // setDeviceVisiable(true);
-                            }}
-                            isPermission={permission.add}
-                            key="add"
-                            icon={<PlusOutlined />}
-                            type="default"
-                            style={{ width: '100%', marginTop: 16}}
-                        >
-                            新增
-                        </PermissionButton>
-                        <div className='item-left-list'>
-                            {
-                                data.map(item => <ChannelCard
-                                    active={activeKey === item.id}
-                                    data={item}
-                                    onClick={() => {
-                                        setActiveKey(item.id)
-                                    }}
-                                    actions={
-                                        <>
-                                            <PermissionButton
-                                                isPermission={permission.update}
-                                                key="edit"
-                                                onClick={() => {
-                                                    // setVisible(true);
-                                                    // setCurrent(record);
-                                                }}
-                                                type={'link'}
-                                                style={{ padding: 0 }}
-                                            >
-                                                <EditOutlined />编辑
-                                            </PermissionButton>
-                                            <Divider type="vertical" />
-                                            <PermissionButton
-                                                isPermission={permission.update}
-                                                key="enbale"
-                                                type={'link'}
-                                                style={{ padding: 0 }}
-                                                popConfirm={{
-                                                    title: intl.formatMessage({
-                                                        id: `pages.data.option.${item.state.value !== 'disabled' ? 'disabled' : 'enabled'
-                                                            }.tips`,
-                                                        defaultMessage: '确认禁用?',
-                                                    }),
-                                                    onConfirm: async () => {
-
-                                                    },
-                                                }}
-                                            >
-                                                {item.state.value === 'enabled' ? <StopOutlined /> : <PlayCircleOutlined />}
-                                                {item.state.value === 'enabled' ? '禁用' : '启用'}
-                                            </PermissionButton>
-                                            <Divider type="vertical" />
-                                            <PermissionButton
-                                                isPermission={permission.delete}
-                                                style={{ padding: 0 }}
-                                                disabled={item.state.value === 'enabled'}
-                                                popConfirm={{
-                                                    title: '确认删除',
-                                                    disabled: item.state.value === 'enabled',
-                                                    onConfirm: async () => {
-
-                                                    },
-                                                }}
-                                                key="delete"
-                                                type="link"
-                                            >
-                                                <DeleteOutlined />
-                                            </PermissionButton>
-                                        </>} />)
-                            }
+  const menu = (
+    <Menu>
+      <Menu.Item key="1">
+        <PermissionButton
+          isPermission={permission.export}
+          icon={<ExportOutlined />}
+          type="default"
+          onClick={() => {
+            // setExportVisible(true);
+          }}
+        >
+          批量导出设备
+        </PermissionButton>
+      </Menu.Item>
+      <Menu.Item key="2">
+        <PermissionButton
+          isPermission={permission.import}
+          icon={<ImportOutlined />}
+          onClick={() => {
+            // setImportVisible(true);
+          }}
+        >
+          批量导入设备
+        </PermissionButton>
+      </Menu.Item>
+    </Menu>
+  );
 
-                        </div>
-                    </div>
-                </div>
-                <div className='item-right'>
-                    <SearchComponent<any>
-                        field={columns}
-                        target="modbus"
-                        onSearch={(data) => {
-                            actionRef.current?.reset?.();
-                            setParam(data);
+  return (
+    <Card className="modbus" style={{ minHeight }}>
+      <div className="item">
+        <div className="item-left">
+          <div style={{ width: 220 }}>
+            <Input.Search
+              placeholder="请输入名称"
+              allowClear
+              onSearch={(value) => {
+                console.log(value);
+              }}
+            />
+            <PermissionButton
+              onClick={() => {
+                // setDeviceVisiable(true);
+              }}
+              isPermission={permission.add}
+              key="add"
+              icon={<PlusOutlined />}
+              type="default"
+              style={{ width: '100%', marginTop: 16 }}
+            >
+              新增
+            </PermissionButton>
+            <div className="item-left-list">
+              {data.map((item) => (
+                <ChannelCard
+                  active={activeKey === item.id}
+                  data={item}
+                  onClick={() => {
+                    setActiveKey(item.id);
+                  }}
+                  actions={
+                    <>
+                      <PermissionButton
+                        isPermission={permission.update}
+                        key="edit"
+                        onClick={() => {
+                          // setVisible(true);
+                          // setCurrent(record);
                         }}
-                    />
-                    <ProTable
-                        actionRef={actionRef}
-                        params={param}
-                        columns={columns}
-                        rowKey="id"
-                        scroll={{ x: '60%' }}
-                        search={false}
-                        headerTitle={
-                            <>
-                                <PermissionButton
-                                    onClick={() => {
-                                        // setMode('add');
-                                        // setVisible(true);
-                                        // setCurrent({});
-                                    }}
-                                    isPermission={permission.add}
-                                    key="add"
-                                    icon={<PlusOutlined />}
-                                    type="primary"
-                                    style={{marginRight: 10 }}
-                                >
-                                    {intl.formatMessage({
-                                        id: 'pages.data.option.add',
-                                        defaultMessage: '新增',
-                                    })}
-                                </PermissionButton>
-                                <Dropdown key={'more'} overlay={menu} placement="bottom" >
-                                    <Button>批量操作</Button>
-                                </Dropdown>
-                            </>
-                        }
-                    // request={async (params) =>
-                    //     service.query({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
-                    // }
-                    />
-                </div>
+                        type={'link'}
+                        style={{ padding: 0 }}
+                      >
+                        <EditOutlined />
+                        编辑
+                      </PermissionButton>
+                      <Divider type="vertical" />
+                      <PermissionButton
+                        isPermission={permission.update}
+                        key="enbale"
+                        type={'link'}
+                        style={{ padding: 0 }}
+                        popConfirm={{
+                          title: intl.formatMessage({
+                            id: `pages.data.option.${
+                              item.state.value !== 'disabled' ? 'disabled' : 'enabled'
+                            }.tips`,
+                            defaultMessage: '确认禁用?',
+                          }),
+                          onConfirm: async () => {},
+                        }}
+                      >
+                        {item.state.value === 'enabled' ? <StopOutlined /> : <PlayCircleOutlined />}
+                        {item.state.value === 'enabled' ? '禁用' : '启用'}
+                      </PermissionButton>
+                      <Divider type="vertical" />
+                      <PermissionButton
+                        isPermission={permission.delete}
+                        style={{ padding: 0 }}
+                        disabled={item.state.value === 'enabled'}
+                        popConfirm={{
+                          title: '确认删除',
+                          disabled: item.state.value === 'enabled',
+                          onConfirm: async () => {},
+                        }}
+                        key="delete"
+                        type="link"
+                      >
+                        <DeleteOutlined />
+                      </PermissionButton>
+                    </>
+                  }
+                />
+              ))}
             </div>
-        </Card >
-    )
-}
-export default NewModbus;
+          </div>
+        </div>
+        <div className="item-right">
+          <SearchComponent<any>
+            field={columns}
+            target="modbus"
+            onSearch={(parms) => {
+              actionRef.current?.reset?.();
+              setParam(parms);
+            }}
+          />
+          <ProTable
+            actionRef={actionRef}
+            params={param}
+            columns={columns}
+            rowKey="id"
+            // scroll={{ x: 1000 }}
+            search={false}
+            headerTitle={
+              <>
+                <PermissionButton
+                  onClick={() => {
+                    // setMode('add');
+                    // setVisible(true);
+                    // setCurrent({});
+                  }}
+                  isPermission={permission.add}
+                  key="add"
+                  icon={<PlusOutlined />}
+                  type="primary"
+                  style={{ marginRight: 10 }}
+                >
+                  {intl.formatMessage({
+                    id: 'pages.data.option.add',
+                    defaultMessage: '新增',
+                  })}
+                </PermissionButton>
+                <Dropdown key={'more'} overlay={menu} placement="bottom">
+                  <Button>批量操作</Button>
+                </Dropdown>
+              </>
+            }
+            // request={async (params) =>
+            //     service.query({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
+            // }
+          />
+        </div>
+      </div>
+    </Card>
+  );
+};
+export default NewModbus;