Browse Source

feat: merge

xieyonghong 3 năm trước cách đây
mục cha
commit
5062ac7ef2
25 tập tin đã thay đổi với 601 bổ sung475 xóa
  1. 5 3
      src/components/ProTableCard/CardItems/Scene/index.tsx
  2. 2 2
      src/components/SearchComponent/index.tsx
  3. 1 0
      src/global.less
  4. 11 2
      src/pages/device/Instance/Detail/Running/Property/FileComponent/Detail.tsx
  5. 1 1
      src/pages/device/Instance/Detail/Running/Property/PropertyCard.less
  6. 15 7
      src/pages/device/Instance/Detail/Running/Property/PropertyCard.tsx
  7. 1 1
      src/pages/link/AccessConfig/index.tsx
  8. 1 1
      src/pages/link/DataCollect/components/Channel/Save/index.tsx
  9. 104 100
      src/pages/link/DataCollect/components/Channel/index.tsx
  10. 32 1
      src/pages/link/DataCollect/components/Device/Save/index.tsx
  11. 20 7
      src/pages/link/DataCollect/components/Device/index.tsx
  12. 3 0
      src/pages/link/DataCollect/components/Point/Save/opc-ua.tsx
  13. 13 7
      src/pages/link/DataCollect/components/Point/index.tsx
  14. 42 22
      src/pages/link/DataCollect/components/Tree/index.tsx
  15. 7 3
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/TypeModel.tsx
  16. 1 1
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/WriteProperty.tsx
  17. 1 9
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/functionCall.tsx
  18. 16 11
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/index.tsx
  19. 1 1
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/index.tsx
  20. 5 1
      src/pages/rule-engine/Scene/Save/components/Buttons/Dropdown.tsx
  21. 0 1
      src/pages/rule-engine/Scene/Save/components/ParamsSelect/index.tsx
  22. 1 1
      src/pages/rule-engine/Scene/Save/save.tsx
  23. 288 288
      src/pages/system/Menu/Setting/baseMenu.ts
  24. 29 4
      src/pages/system/Permission/Save/index.tsx
  25. 1 1
      src/pages/system/Permission/index.tsx

+ 5 - 3
src/components/ProTableCard/CardItems/Scene/index.tsx

@@ -278,8 +278,10 @@ const actionRender = (action: ActionsType, index: number) => {
 const conditionsRender = (when: any[], index: number) => {
   if (when.length && when[index]) {
     let str: string = '';
-    (when[index]?.terms || []).map((i: any) => {
-      str += `${i?.terms[0] || ''}${i?.termType || ''}`;
+    (when[index]?.terms || []).map((i: any, _index: number) => {
+      str += `${i?.terms[0] || ''}${
+        i?.termType && when[index]?.terms.length !== _index + 1 ? i?.termType : ''
+      }`;
     });
     return str;
   }
@@ -374,7 +376,7 @@ const ContentRender = (data: SceneCardProps) => {
                       {item?.then && item?.then.length && (
                         <div
                           className={styles['right-item-right']}
-                          style={{ width: type === 'device' ? '85%' : '15%' }}
+                          style={{ width: type === 'device' ? '85%' : '100%' }}
                         >
                           {(item?.then || []).map((i: BranchesThen, _index: number) => (
                             <div key={i?.key || _index} className={styles['right-item-right-item']}>

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

@@ -663,8 +663,8 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
         handleSearch(false);
         return;
       }
-      form.setInitialValues(JSON.parse(q));
-      handleSearch(false);
+      // form.setInitialValues(JSON.parse(q));
+      // handleSearch(false);
     }
   };
 

+ 1 - 0
src/global.less

@@ -161,4 +161,5 @@ input[type='tel'] {
 
 .ant-popover-buttons {
   display: flex;
+  justify-content: flex-end;
 }

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

@@ -1,5 +1,6 @@
 import LivePlayer from '@/components/Player';
-import { Image, Input, Modal } from 'antd';
+import { Image, Modal } from 'antd';
+import ReactJson from 'react-json-view';
 
 interface Props {
   close: () => void;
@@ -16,7 +17,15 @@ const Detail = (props: Props) => {
     } else if (['.flv', '.m3u8', '.mp4'].includes(type)) {
       return <LivePlayer live={false} url={value?.formatValue} />;
     } else if (type === 'obj') {
-      return <Input.TextArea rows={15} bordered={false} value={value?.formatValue} />;
+      // @ts-ignore
+      return (
+        <ReactJson
+          displayObjectSize={false}
+          displayDataTypes={false}
+          name={false}
+          src={value?.formatValue}
+        />
+      );
     }
     return null;
   };

+ 1 - 1
src/pages/device/Instance/Detail/Running/Property/PropertyCard.less

@@ -22,7 +22,7 @@
   }
 }
 
-.value {
+.time-value {
   width: 100%;
   overflow: hidden;
   white-space: nowrap;

+ 15 - 7
src/pages/device/Instance/Detail/Running/Property/PropertyCard.tsx

@@ -106,14 +106,22 @@ const Property = (props: Props) => {
           <FileComponent type="card" value={dataValue} data={data} />
           <div style={{ marginTop: 10 }}>
             <div style={{ color: 'rgba(0, 0, 0, .65)', fontSize: 12 }}>更新时间</div>
-            <div
-              style={{ marginTop: 5, fontSize: 16, color: 'black', minHeight: 25 }}
-              className="value"
+            <Tooltip
+              title={
+                dataValue?.timestamp
+                  ? moment(dataValue?.timestamp).format('YYYY-MM-DD HH:mm:ss')
+                  : ''
+              }
             >
-              {dataValue?.timestamp
-                ? moment(dataValue?.timestamp).format('YYYY-MM-DD HH:mm:ss')
-                : ''}
-            </div>
+              <div
+                style={{ marginTop: 5, fontSize: 16, color: 'black', minHeight: 25 }}
+                className="time-value"
+              >
+                {dataValue?.timestamp
+                  ? moment(dataValue?.timestamp).format('YYYY-MM-DD HH:mm:ss')
+                  : ''}
+              </div>
+            </Tooltip>
           </div>
         </div>
       </Spin>

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

@@ -26,7 +26,7 @@ const AccessConfig = () => {
   const [param, setParam] = useState<any>({ pageSize: 10, terms: [] });
   const { permission } = PermissionButton.usePermission('link/AccessConfig');
 
-  const { minHeight } = useDomFullHeight(`.link-accessConfig`, 36);
+  const { minHeight } = useDomFullHeight(`.link-accessConfig`, 24);
 
   const columns: ProColumns<any>[] = [
     {

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

@@ -107,7 +107,7 @@ export default (props: Props) => {
         },
         properties: {
           name: {
-            title: '名称',
+            title: '通道名称',
             'x-component': 'Input',
             'x-decorator': 'FormItem',
             'x-decorator-props': {

+ 104 - 100
src/pages/link/DataCollect/components/Channel/index.tsx

@@ -27,7 +27,7 @@ const ChannelModel = model<{
 
 export default observer((props: Props) => {
   const intl = useIntl();
-  const { minHeight } = useDomFullHeight(`.data-collect-channel`, 24);
+  const { minHeight } = useDomFullHeight(`.data-collect-channel-card`, 24);
   const [param, setParam] = useState({ pageSize: 12, terms: [] });
   const { permission } = PermissionButton.usePermission('link/DataCollect/DataGathering');
   const [loading, setLoading] = useState<boolean>(true);
@@ -40,7 +40,7 @@ export default observer((props: Props) => {
 
   const columns: ProColumns<ChannelItem>[] = [
     {
-      title: '名称',
+      title: '通道名称',
       dataIndex: 'name',
     },
     {
@@ -148,106 +148,110 @@ export default observer((props: Props) => {
           handleSearch(dt);
         }}
       />
-      <Card loading={loading} bordered={false}>
-        <div style={{ position: 'relative', minHeight }}>
-          <div style={{ height: '100%', paddingBottom: 48 }}>
-            {dataSource?.data.length ? (
-              <>
-                <Row gutter={[24, 24]} style={{ marginTop: 10 }}>
-                  {(dataSource?.data || []).map((record: any) => (
-                    <Col key={record.id} span={props.type ? 8 : 12}>
-                      <ChannelCard
-                        {...record}
-                        state={getState(record)}
-                        actions={[
-                          <PermissionButton
-                            type={'link'}
-                            onClick={() => {
-                              ChannelModel.current = record;
-                              ChannelModel.visible = true;
-                            }}
-                            key={'edit'}
-                            isPermission={permission.update}
-                          >
-                            <EditOutlined />
-                            {intl.formatMessage({
-                              id: 'pages.data.option.edit',
-                              defaultMessage: '编辑',
-                            })}
-                          </PermissionButton>,
-                          <PermissionButton
-                            key="delete"
-                            isPermission={permission.delete}
-                            type={'link'}
-                            style={{ padding: 0 }}
-                            // disabled={record?.state?.value !== 'disabled'}
-                            // tooltip={
-                            //   record?.state?.value !== 'disabled'
-                            //     ? {
-                            //         title: '正常的通道不能删除',
-                            //       }
-                            //     : undefined
-                            // }
-                            popConfirm={{
-                              title: '该操作将会删除下属采集器与点位,确定删除?',
-                              onConfirm: async () => {
-                                await service.removeChannel(record.id);
-                                handleSearch(param);
-                                onlyMessage(
-                                  intl.formatMessage({
-                                    id: 'pages.data.option.success',
-                                    defaultMessage: '操作成功!',
-                                  }),
-                                );
-                              },
-                            }}
-                          >
-                            <DeleteOutlined />
-                          </PermissionButton>,
-                        ]}
-                      />
-                    </Col>
-                  ))}
-                </Row>
-                <div
-                  style={{
-                    display: 'flex',
-                    justifyContent: 'flex-end',
-                    position: 'absolute',
-                    width: '100%',
-                    bottom: 0,
-                  }}
-                >
-                  <Pagination
-                    showSizeChanger
-                    size="small"
-                    className={'pro-table-card-pagination'}
-                    total={dataSource?.total || 0}
-                    current={dataSource?.pageIndex + 1}
-                    onChange={(page, size) => {
-                      handleSearch({
-                        ...param,
-                        pageIndex: page - 1,
-                        pageSize: size,
-                      });
-                    }}
-                    pageSizeOptions={[12, 24, 48, 96]}
-                    pageSize={dataSource?.pageSize}
-                    showTotal={(num) => {
-                      const minSize = dataSource?.pageIndex * dataSource?.pageSize + 1;
-                      const MaxSize = (dataSource?.pageIndex + 1) * dataSource?.pageSize;
-                      return `第 ${minSize} - ${MaxSize > num ? num : MaxSize} 条/总共 ${num} 条`;
-                    }}
+      <Card
+        loading={loading}
+        bordered={false}
+        style={{ position: 'relative', minHeight }}
+        className={'data-collect-channel-card'}
+      >
+        <div style={{ height: '100%', paddingBottom: 48 }}>
+          {dataSource?.data.length > 0 ? (
+            <Row gutter={[24, 24]} style={{ marginTop: 10 }}>
+              {(dataSource?.data || []).map((record: any) => (
+                <Col key={record.id} span={props.type ? 8 : 12}>
+                  <ChannelCard
+                    {...record}
+                    state={getState(record)}
+                    actions={[
+                      <PermissionButton
+                        type={'link'}
+                        onClick={() => {
+                          ChannelModel.current = record;
+                          ChannelModel.visible = true;
+                        }}
+                        key={'edit'}
+                        isPermission={permission.update}
+                      >
+                        <EditOutlined />
+                        {intl.formatMessage({
+                          id: 'pages.data.option.edit',
+                          defaultMessage: '编辑',
+                        })}
+                      </PermissionButton>,
+                      <PermissionButton
+                        key="delete"
+                        isPermission={permission.delete}
+                        type={'link'}
+                        style={{ padding: 0 }}
+                        // disabled={record?.state?.value !== 'disabled'}
+                        // tooltip={
+                        //   record?.state?.value !== 'disabled'
+                        //     ? {
+                        //         title: '正常的通道不能删除',
+                        //       }
+                        //     : undefined
+                        // }
+                        popConfirm={{
+                          title: '该操作将会删除下属采集器与点位,确定删除?',
+                          placement: 'topRight',
+                          onConfirm: async () => {
+                            await service.removeChannel(record.id);
+                            handleSearch(param);
+                            onlyMessage(
+                              intl.formatMessage({
+                                id: 'pages.data.option.success',
+                                defaultMessage: '操作成功!',
+                              }),
+                            );
+                          },
+                        }}
+                      >
+                        <DeleteOutlined />
+                      </PermissionButton>,
+                    ]}
                   />
-                </div>
-              </>
-            ) : (
-              <div style={{ height: minHeight - 150 }}>
-                <Empty />
-              </div>
-            )}
-          </div>
+                </Col>
+              ))}
+            </Row>
+          ) : (
+            <div style={{ height: minHeight - 150 }}>
+              <Empty />
+            </div>
+          )}
         </div>
+        {dataSource?.data?.length > 0 && (
+          <div
+            style={{
+              display: 'flex',
+              justifyContent: 'flex-end',
+              position: 'absolute',
+              width: '100%',
+              bottom: 0,
+            }}
+          >
+            <Pagination
+              showSizeChanger
+              size="small"
+              className={'pro-table-card-pagination'}
+              total={dataSource?.total || 0}
+              current={dataSource?.pageIndex + 1}
+              onChange={(page, size) => {
+                handleSearch({
+                  ...param,
+                  pageIndex: page - 1,
+                  pageSize: size,
+                });
+              }}
+              pageSizeOptions={[12, 24, 48, 96]}
+              pageSize={dataSource?.pageSize}
+              showTotal={(num) => {
+                const minSize = dataSource?.pageIndex * dataSource?.pageSize + 1;
+                const MaxSize = (dataSource?.pageIndex + 1) * dataSource?.pageSize;
+                return `第 ${minSize} - ${MaxSize > num ? num : MaxSize} 条/总共 ${num} 条`;
+              }}
+            />
+          </div>
+        )}
       </Card>
       {ChannelModel.visible && (
         <Save

+ 32 - 1
src/pages/link/DataCollect/components/Device/Save/index.tsx

@@ -89,7 +89,7 @@ export default (props: Props) => {
         },
         properties: {
           name: {
-            title: '名称',
+            title: '采集器名称',
             'x-component': 'Input',
             'x-decorator': 'FormItem',
             'x-decorator-props': {
@@ -166,6 +166,37 @@ export default (props: Props) => {
               },
             ],
           },
+          'configuration.endian': {
+            title: '大小端',
+            'x-component': 'RadioCard',
+            'x-decorator': 'FormItem',
+            'x-decorator-props': {
+              gridSpan: 2,
+            },
+            'x-component-props': {
+              placeholder: '请选择大小端',
+              model: 'singular',
+              itemStyle: {
+                display: 'flex',
+                flexDirection: 'column',
+                justifyContent: 'space-around',
+                minWidth: '130px',
+                height: '50px',
+              },
+              options: [
+                { label: '大端', value: 'BIG' },
+                { label: '小端', value: 'LITTLE' },
+              ],
+            },
+            'x-visible': props.provider === 'MODBUS_TCP',
+            default: 'BIG',
+            'x-validator': [
+              {
+                required: true,
+                message: '请选择大小端',
+              },
+            ],
+          },
           description: {
             title: '说明',
             'x-component': 'Input.TextArea',

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

@@ -7,7 +7,13 @@ import service from '@/pages/link/DataCollect/service';
 import CollectorCard from '@/components/ProTableCard/CardItems/DataCollect/device';
 import { Empty, PermissionButton } from '@/components';
 import { useIntl } from '@@/plugin-locale/localeExports';
-import { DeleteOutlined, EditOutlined, PlayCircleOutlined, StopOutlined } from '@ant-design/icons';
+import {
+  DeleteOutlined,
+  EditOutlined,
+  PlayCircleOutlined,
+  PlusOutlined,
+  StopOutlined,
+} from '@ant-design/icons';
 import { onlyMessage } from '@/utils/util';
 import { Card, Col, Pagination, Row } from 'antd';
 import { model } from '@formily/reactive';
@@ -45,7 +51,7 @@ export default observer((props: Props) => {
   const columns: ProColumns<CollectorItem>[] = props.type
     ? [
         {
-          title: '名称',
+          title: '采集器名称',
           dataIndex: 'name',
         },
         {
@@ -108,7 +114,7 @@ export default observer((props: Props) => {
       ]
     : [
         {
-          title: '名称',
+          title: '采集器名称',
           dataIndex: 'name',
         },
         {
@@ -208,8 +214,13 @@ export default observer((props: Props) => {
           handleSearch(dt);
         }}
       />
-      <Card bordered={false} loading={loading}>
-        <div style={{ minHeight, position: 'relative' }}>
+      <Card
+        bordered={false}
+        loading={loading}
+        style={{ minHeight, position: 'relative' }}
+        className={'data-collect-collector'}
+      >
+        <div>
           <div style={{ paddingBottom: 48, height: '100%' }}>
             {!props.type && (
               <div style={{ width: '100%', display: 'flex', justifyContent: 'flex-start' }}>
@@ -221,8 +232,9 @@ export default observer((props: Props) => {
                   }}
                   key="button"
                   type="primary"
+                  icon={<PlusOutlined />}
                 >
-                  新增
+                  新增采集器
                 </PermissionButton>
               </div>
             )}
@@ -311,6 +323,7 @@ export default observer((props: Props) => {
                             popConfirm={{
                               title: '该操作将会删除下属点位,确定删除?',
                               disabled: record?.state?.value !== 'disabled',
+                              placement: 'topRight',
                               onConfirm: async () => {
                                 if (record?.state?.value === 'disabled') {
                                   await service.removeCollector(record.id);
@@ -384,7 +397,7 @@ export default observer((props: Props) => {
         <Save
           data={CollectorModel.current}
           channelId={props.id}
-          provider={props.provider}
+          provider={props.provider || CollectorModel.current?.provider}
           close={() => {
             CollectorModel.visible = false;
           }}

+ 3 - 0
src/pages/link/DataCollect/components/Point/Save/opc-ua.tsx

@@ -34,6 +34,9 @@ export default (props: Props) => {
       accessModes: props.data?.accessModes
         ? (props.data?.accessModes || []).map((item) => item.value)
         : [],
+      features: props.data?.features
+        ? (props.data?.features || []).map((item: any) => item?.value)
+        : [],
     });
   }, [props.data]);
 

+ 13 - 7
src/pages/link/DataCollect/components/Point/index.tsx

@@ -16,7 +16,7 @@ import OpcSave from '@/pages/link/DataCollect/components/Point/Save/opc-ua';
 import WritePoint from '@/pages/link/DataCollect/components/Point/CollectorCard/WritePoint';
 import BatchUpdate from './Save/BatchUpdate';
 import { onlyMessage } from '@/utils/util';
-import { DeleteOutlined, EditOutlined, RedoOutlined } from '@ant-design/icons';
+import { DeleteOutlined, EditOutlined, PlusOutlined, RedoOutlined } from '@ant-design/icons';
 interface Props {
   type: boolean; // true: 综合查询  false: 数据采集
   data?: Partial<CollectorItem>;
@@ -59,7 +59,7 @@ const PointModel = model<{
 
 const PointCard = observer((props: PointCardProps) => {
   const [subscribeTopic] = useSendWebsocketMessage();
-  const { minHeight } = useDomFullHeight(`.data-collect-point`, 24);
+  const { minHeight } = useDomFullHeight(`.data-collect-point`);
   const [param, setParam] = useState({ pageSize: 12, terms: [] });
   const [loading, setLoading] = useState<boolean>(true);
   const { permission } = PermissionButton.usePermission('link/DataCollect/DataGathering');
@@ -207,8 +207,13 @@ const PointCard = observer((props: PointCardProps) => {
           handleSearch(dt);
         }}
       />
-      <Card loading={loading} bordered={false}>
-        <div style={{ position: 'relative', minHeight }}>
+      <Card
+        loading={loading}
+        bordered={false}
+        className={'data-collect-point'}
+        style={{ position: 'relative', minHeight }}
+      >
+        <div>
           <div style={{ height: '100%', paddingBottom: 48 }}>
             {!props.type && (
               <div style={{ width: '100%', display: 'flex', justifyContent: 'flex-start' }}>
@@ -229,8 +234,9 @@ const PointCard = observer((props: PointCardProps) => {
                   }}
                   key="button"
                   type="primary"
+                  icon={<PlusOutlined />}
                 >
-                  {props?.provider === 'OPC_UA' ? '扫描' : '新增'}
+                  {props?.provider === 'OPC_UA' ? '扫描' : '新增点位'}
                 </PermissionButton>
                 {props.provider === 'OPC_UA' && (
                   <Dropdown key={'more'} overlay={menu} placement="bottom">
@@ -357,7 +363,7 @@ export default observer((props: Props) => {
   const columns: ProColumns<PointItem>[] = props.type
     ? [
         {
-          title: '名称',
+          title: '点位名称',
           dataIndex: 'name',
         },
         {
@@ -439,7 +445,7 @@ export default observer((props: Props) => {
       ]
     : [
         {
-          title: '名称',
+          title: '点位名称',
           dataIndex: 'name',
         },
         {

+ 42 - 22
src/pages/link/DataCollect/components/Tree/index.tsx

@@ -6,10 +6,10 @@ import {
   StopOutlined,
   PlayCircleOutlined,
 } from '@ant-design/icons';
-import { Button, Input, Tree, Space, Popconfirm, Tooltip } from 'antd';
+import { Button, Input, Tree, Space, Popconfirm, Tooltip, Tag } from 'antd';
 import { observer } from '@formily/react';
 import { model } from '@formily/reactive';
-import { Empty, PermissionButton } from '@/components';
+import { Ellipsis, Empty, PermissionButton } from '@/components';
 import styles from './index.less';
 import service from '@/pages/link/DataCollect/service';
 import { useEffect } from 'react';
@@ -96,6 +96,29 @@ export default observer((props: Props) => {
   //   };
   // };
 
+  const getState = (record: any) => {
+    if (record) {
+      const colorMap = new Map();
+      colorMap.set('running', 'success');
+      colorMap.set('partialError', 'warning');
+      colorMap.set('failed', 'error');
+      colorMap.set('stopped', 'default');
+      if (record?.state?.value === 'enabled') {
+        return (
+          record?.runningState && (
+            <Tag color={colorMap.get(record?.runningState?.value)}>
+              {record?.runningState?.text}
+            </Tag>
+          )
+        );
+      } else {
+        return <Tag color="processing">禁用</Tag>;
+      }
+    } else {
+      return '';
+    }
+  };
+
   return (
     <div>
       <div>
@@ -113,6 +136,7 @@ export default observer((props: Props) => {
       <div style={{ margin: '16px 0' }}>
         <Button
           type="primary"
+          ghost
           style={{ width: '100%' }}
           icon={<PlusOutlined />}
           onClick={() => {
@@ -120,7 +144,7 @@ export default observer((props: Props) => {
             TreeModel.current = {};
           }}
         >
-          新增
+          新增通道
         </Button>
       </div>
       <div>
@@ -145,23 +169,9 @@ export default observer((props: Props) => {
                         }}
                       >
                         <img width={'20px'} style={{ marginRight: 5 }} src={channelImg} />
-                        <div className={'ellipsis'}>
-                          {/* <BadgeStatus
-                            status={
-                              item && getState(item) && getState(item)?.value
-                                ? getState(item).value
-                                : ''
-                            }
-                            text={item.name}
-                            statusNames={{
-                              running: StatusColorEnum.success,
-                              disabled: StatusColorEnum.processing,
-                              partialError: StatusColorEnum.warning,
-                              failed: StatusColorEnum.error,
-                              stopped: StatusColorEnum.default,
-                            }}
-                          /> */}
-                          {item.name}
+                        <div style={{ display: 'flex' }}>
+                          <Ellipsis title={item.name} style={{ marginRight: 5, maxWidth: 120 }} />
+                          {getState(item)}
                         </div>
                       </div>
                       <div>
@@ -211,8 +221,18 @@ export default observer((props: Props) => {
                             }}
                           >
                             <img width={'20px'} style={{ marginRight: 5 }} src={deviceImg} />
-                            <div style={{ width: '120px' }} className={'ellipsis'}>
-                              {i.name}
+                            <div style={{ display: 'flex' }}>
+                              <span
+                                className={'ellipsis'}
+                                style={{
+                                  marginRight: 5,
+                                  maxWidth: 90,
+                                  color: 'rgba(0, 0, 0, 0.6)',
+                                }}
+                              >
+                                {i.name}
+                              </span>
+                              {getState(i)}
                             </div>
                           </div>
                           <div>

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

@@ -20,7 +20,7 @@ interface Props {
 }
 
 export default (props: Props) => {
-  const [value, setValue] = useState<any>(props.value || '');
+  const [value, setValue] = useState<any>(props.value || undefined);
   const [visible, setVisible] = useState<boolean>(false);
   const [objVisiable, setObjVisable] = useState<boolean>(false);
   const [source, setSource] = useState<string>(props.source || 'fixed');
@@ -49,6 +49,7 @@ export default (props: Props) => {
 
   const onChange = (params: any) => {
     setValue(params);
+    setLabelValue(params);
     if (props.onChange) {
       props.onChange(params, source);
     }
@@ -86,6 +87,7 @@ export default (props: Props) => {
             placeholder={'请选择'}
             mode="multiple"
             onChange={(e) => {
+              console.log(e);
               onChange(e);
             }}
           />
@@ -147,6 +149,7 @@ export default (props: Props) => {
             value={moment(value, 'HH:mm:ss')}
             onChange={(_: any, timeString: string) => {
               setValue(timeString);
+              setLabelValue(timeString);
               if (props.onChange) {
                 props.onChange(timeString);
               }
@@ -160,6 +163,7 @@ export default (props: Props) => {
             placeholder={'请输入'}
             onChange={(e) => {
               setValue(e.target.value);
+              setLabelValue(e.target.value);
               if (props.onChange) {
                 props.onChange(e.target.value, source);
               }
@@ -185,7 +189,7 @@ export default (props: Props) => {
           defaultExpandAll
           fieldNames={{ title: 'name', key: 'id' }}
           onSelect={(selectedKeys, e) => {
-            console.log(e.node);
+            // console.log(e.node);
             setLabelValue(e.node.description);
             setValue(selectedKeys[0]);
             if (props.onChange) {
@@ -208,7 +212,7 @@ export default (props: Props) => {
         itemList={itemList}
         value={value}
         onChange={(val: any, tabKey: any) => {
-          console.log(val, tabKey);
+          // console.log(val, tabKey);
           setValue(val);
           setSource(tabKey);
           if (props.onChange) {

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

@@ -48,7 +48,7 @@ export default (props: Props) => {
     } else {
       setPropertiesValue(undefined);
     }
-  }, [props.value, props.properties]);
+  }, [props.properties]);
 
   useEffect(() => {
     if (props.onChange && propertiesValue) {

+ 1 - 9
src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/functionCall.tsx

@@ -16,7 +16,6 @@ interface FunctionCallProps {
   value?: any;
   onChange?: (data: any) => void;
   name?: any;
-  productId?: string;
 }
 
 export default (props: FunctionCallProps) => {
@@ -27,7 +26,6 @@ export default (props: FunctionCallProps) => {
     if (props.functionData && props.functionData.length) {
       setEditableRowKeys(props.functionData.map((d) => d.id));
       if (props.value) {
-        // console.log(props.functionData, 11111111111);
         const tableData = props.functionData.map((item: any) => {
           const oldValue = props.value.find((oldItem: any) => oldItem.name === item.id);
           if (oldValue) {
@@ -53,12 +51,6 @@ export default (props: FunctionCallProps) => {
     }
   }, [props.value, props.functionData]);
 
-  useEffect(() => {
-    if (props.productId && props.onChange) {
-      props.onChange([]);
-    }
-  }, [props.productId]);
-
   const getItemNode = (record: any) => {
     const type = record.type;
     return <TypeModel value={record.value} type={type} record={record} name={props.name} />;
@@ -95,7 +87,7 @@ export default (props: FunctionCallProps) => {
       submitter={false}
       onValuesChange={() => {
         const values = formRef.current?.getFieldsValue();
-        console.log(values, 'values');
+        // console.log(values, 'values');
         if (props.onChange) {
           props.onChange(
             values.table.map((item: any) => ({

+ 16 - 11
src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/index.tsx

@@ -16,7 +16,7 @@ export default observer((props: Props) => {
   const [form] = Form.useForm();
   const [deviceMessageType, setDeviceMessageType] = useState('');
   const [properties, setProperties] = useState([]); // 物模型-属性
-  const [propertiesId, setPropertiesId] = useState<string | undefined>(''); // 物模型-属性ID,用于串行
+  // const [propertiesId, setPropertiesId] = useState<string | undefined>(''); // 物模型-属性ID,用于串行
   const [functionList, setFunctionList] = useState<any>([]); // 物模型-功能
   const [functionId, setFunctionId] = useState('');
   const [functions, setFunctions] = useState([]);
@@ -43,14 +43,12 @@ export default observer((props: Props) => {
   ];
 
   useEffect(() => {
-    // console.log(DeviceModel.message)
-    setDeviceMessageType(DeviceModel.message.messageType);
     if (DeviceModel.productDetail) {
       const metadata = JSON.parse(DeviceModel.productDetail?.metadata || '{}');
       setProperties(metadata.properties);
       setFunctions(metadata.functions);
     }
-  }, [DeviceModel.productDetail, functionId]);
+  }, [DeviceModel.productDetail]);
 
   useEffect(() => {
     if (functionId && functions.length !== 0) {
@@ -71,12 +69,21 @@ export default observer((props: Props) => {
           });
         }
         setFunctionList(array);
-        console.log(propertiesId, 'array');
       }
     }
   }, [functions, functionId]);
 
   useEffect(() => {
+    if (DeviceModel.message.messageType) {
+      setDeviceMessageType(DeviceModel.message.messageType);
+    }
+    if (DeviceModel.message.functionId) {
+      setFunctionId(DeviceModel.message.functionId);
+    }
+    // console.log(DeviceModel.message)
+  }, [DeviceModel.message]);
+
+  useEffect(() => {
     props.get(form);
   }, [form]);
 
@@ -93,12 +100,14 @@ export default observer((props: Props) => {
           name={['message', 'messageType']}
           label="动作类型"
           required
+          rules={[{ required: true, message: '请选择动作类型' }]}
           // initialValue="WRITE_PROPERTY"
         >
           <TopCard
             typeList={TypeList}
             onChange={(value: string) => {
               setDeviceMessageType(value);
+              console.log(value);
             }}
           />
         </Form.Item>
@@ -129,11 +138,7 @@ export default observer((props: Props) => {
                 name={['message', 'inputs']}
                 rules={[{ required: true, message: '请输入功能值' }]}
               >
-                <FunctionCall
-                  functionData={functionList}
-                  productId={DeviceModel.productId[0]}
-                  name={props.name}
-                />
+                <FunctionCall functionData={functionList} name={props.name} />
               </Form.Item>
             )}
           </>
@@ -144,7 +149,7 @@ export default observer((props: Props) => {
             label="读取属性"
             rules={[{ required: true, message: '请选择读取属性' }]}
           >
-            <ReadProperty properties={properties} propertiesChange={setPropertiesId} />
+            <ReadProperty properties={properties} />
           </Form.Item>
         )}
         {deviceMessageType === 'WRITE_PROPERTY' && (

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

@@ -132,7 +132,7 @@ export default observer((props: Props) => {
     <Modal
       title={'执行动作'}
       open
-      width={800}
+      width={860}
       onCancel={() => {
         props.cancel();
         DeviceModel.current = 0;

+ 5 - 1
src/pages/rule-engine/Scene/Save/components/Buttons/Dropdown.tsx

@@ -124,9 +124,13 @@ const DropdownButton = (props: DropdownButtonProps) => {
       <div
         className={classNames(styles['dropdown-button'], props.className, typeClassName)}
         onClick={() => {
-          if (props.options.length === 0) {
+          console.log(props.options);
+          if (props.options.length === 0 && props.type !== 'termType') {
             onlyMessage('请先配置设备触发规则', 'warning');
           }
+          if (props.options.length === 0 && props.type === 'termType') {
+            onlyMessage('请先配置属性值', 'warning');
+          }
         }}
       >
         {label || props.placeholder}

+ 0 - 1
src/pages/rule-engine/Scene/Save/components/ParamsSelect/index.tsx

@@ -84,7 +84,6 @@ export default (props: Props) => {
           {...props.inputProps}
           value={props.labelValue ? props.labelValue : value}
           onChange={(e) => {
-            console.log(111111);
             setValue(e.target.value);
             props.onChange(value, tabKey);
           }}

+ 1 - 1
src/pages/rule-engine/Scene/Save/save.tsx

@@ -30,6 +30,7 @@ export default (props: Props) => {
       onCancel={() => {
         props.close();
       }}
+      width={750}
       onOk={async () => {
         const values = await form.validateFields();
         const obj = {
@@ -53,7 +54,6 @@ export default (props: Props) => {
           }
         }
       }}
-      width={700}
     >
       <Form name="scene-save" layout={'vertical'} form={form} autoComplete="off">
         <Form.Item

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

@@ -1362,298 +1362,298 @@ export default [
               },
             ],
           },
+        ],
+      },
+      {
+        code: 'link/DataCollect',
+        name: '数据采集',
+        owner: 'iot',
+        sortIndex: 10,
+        url: '/iot/link/DataCollect',
+        icon: 'icon-shuxingpeizhi',
+        showPage: [],
+        permissions: [],
+        children: [
           {
-            code: 'link/DataCollect',
+            code: 'DataCollect/Dashboard',
+            name: '仪表盘',
+            owner: 'iot',
+            sortIndex: 1,
+            url: '/iot/DataCollect/Dashboard',
+            icon: 'icon-shujumoni',
+            showPage: [
+              'dashboard',
+              'data-collect-channel',
+              'data-collect-opc',
+              'data-collector',
+              'things-collector',
+            ],
+            permissions: [
+              { permission: 'dashboard', actions: ['query'] },
+              { permission: 'data-collect-channel', actions: ['query'] },
+              { permission: 'data-collect-opc', actions: ['query'] },
+              { permission: 'data-collector', actions: ['query'] },
+              { permission: 'things-collector', actions: ['query'] },
+            ],
+            buttons: [],
+          },
+          {
+            code: 'DataCollect/DataGathering',
             name: '数据采集',
             owner: 'iot',
-            sortIndex: 10,
-            url: '/iot/link/DataCollect',
-            icon: 'icon-shuxingpeizhi',
-            showPage: [],
+            sortIndex: 2,
+            url: '/iot/DataCollect/DataGathering',
+            icon: 'icon-rizhifuwu',
+            showPage: [
+              'data-collect-channel',
+              'data-collect-opc',
+              'data-collector',
+              'things-collector',
+            ],
+            permissions: [],
+            buttons: [
+              {
+                id: 'view',
+                name: '查看',
+                permissions: [
+                  {
+                    permission: 'data-collect-channel',
+                    actions: ['query'],
+                  },
+                  {
+                    permission: 'data-collector',
+                    actions: ['query'],
+                  },
+                  {
+                    permission: 'data-collect-opc',
+                    actions: ['query'],
+                  },
+                  {
+                    permission: 'things-collector',
+                    actions: ['query'],
+                  },
+                ],
+              },
+              {
+                id: 'add',
+                name: '新增',
+                permissions: [
+                  {
+                    permission: 'data-collect-channel',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collector',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collect-opc',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'things-collector',
+                    actions: ['save', 'query'],
+                  },
+                ],
+              },
+              {
+                id: 'update',
+                name: '编辑',
+                permissions: [
+                  {
+                    permission: 'data-collect-channel',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collector',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collect-opc',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'things-collector',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'certificate',
+                    actions: ['query'],
+                  },
+                ],
+              },
+              {
+                id: 'action',
+                name: '禁用/启用',
+                permissions: [
+                  {
+                    permission: 'data-collect-channel',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collector',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collect-opc',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'things-collector',
+                    actions: ['save', 'query'],
+                  },
+                ],
+              },
+              {
+                id: 'delete',
+                name: '删除',
+                permissions: [
+                  {
+                    permission: 'data-collect-channel',
+                    actions: ['delete', 'query'],
+                  },
+                  {
+                    permission: 'data-collector',
+                    actions: ['delete', 'query'],
+                  },
+                  {
+                    permission: 'data-collect-opc',
+                    actions: ['delete', 'query'],
+                  },
+                  {
+                    permission: 'things-collector',
+                    actions: ['delete', 'query'],
+                  },
+                ],
+              },
+            ],
+          },
+          {
+            code: 'DataCollect/IntegratedQuery',
+            name: '综合查询',
+            owner: 'iot',
+            sortIndex: 3,
+            url: '/iot/DataCollect/IntegratedQuery',
+            icon: 'icon-zhilianshebei',
+            showPage: [
+              'data-collect-channel',
+              'data-collect-opc',
+              'data-collector',
+              'things-collector',
+            ],
             permissions: [],
-            children: [
-              {
-                code: 'link/DataCollect/Dashboard',
-                name: '仪表盘',
-                owner: 'iot',
-                sortIndex: 1,
-                url: '/iot/link/DataCollect/Dashboard',
-                icon: 'icon-shujumoni',
-                showPage: [
-                  'dashboard',
-                  'data-collect-channel',
-                  'data-collect-opc',
-                  'data-collector',
-                  'things-collector',
-                ],
-                permissions: [
-                  { permission: 'dashboard', actions: ['query'] },
-                  { permission: 'data-collect-channel', actions: ['query'] },
-                  { permission: 'data-collect-opc', actions: ['query'] },
-                  { permission: 'data-collector', actions: ['query'] },
-                  { permission: 'things-collector', actions: ['query'] },
-                ],
-                buttons: [],
-              },
-              {
-                code: 'link/DataCollect/DataGathering',
-                name: '数据采集',
-                owner: 'iot',
-                sortIndex: 2,
-                url: '/iot/link/DataCollect/DataGathering',
-                icon: 'icon-rizhifuwu',
-                showPage: [
-                  'data-collect-channel',
-                  'data-collect-opc',
-                  'data-collector',
-                  'things-collector',
-                ],
-                permissions: [],
-                buttons: [
-                  {
-                    id: 'view',
-                    name: '查看',
-                    permissions: [
-                      {
-                        permission: 'data-collect-channel',
-                        actions: ['query'],
-                      },
-                      {
-                        permission: 'data-collector',
-                        actions: ['query'],
-                      },
-                      {
-                        permission: 'data-collect-opc',
-                        actions: ['query'],
-                      },
-                      {
-                        permission: 'things-collector',
-                        actions: ['query'],
-                      },
-                    ],
-                  },
-                  {
-                    id: 'add',
-                    name: '新增',
-                    permissions: [
-                      {
-                        permission: 'data-collect-channel',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collector',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collect-opc',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'things-collector',
-                        actions: ['save', 'query'],
-                      },
-                    ],
-                  },
-                  {
-                    id: 'update',
-                    name: '编辑',
-                    permissions: [
-                      {
-                        permission: 'data-collect-channel',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collector',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collect-opc',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'things-collector',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'certificate',
-                        actions: ['query'],
-                      },
-                    ],
-                  },
-                  {
-                    id: 'action',
-                    name: '禁用/启用',
-                    permissions: [
-                      {
-                        permission: 'data-collect-channel',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collector',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collect-opc',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'things-collector',
-                        actions: ['save', 'query'],
-                      },
-                    ],
-                  },
-                  {
-                    id: 'delete',
-                    name: '删除',
-                    permissions: [
-                      {
-                        permission: 'data-collect-channel',
-                        actions: ['delete', 'query'],
-                      },
-                      {
-                        permission: 'data-collector',
-                        actions: ['delete', 'query'],
-                      },
-                      {
-                        permission: 'data-collect-opc',
-                        actions: ['delete', 'query'],
-                      },
-                      {
-                        permission: 'things-collector',
-                        actions: ['delete', 'query'],
-                      },
-                    ],
-                  },
-                ],
-              },
-              {
-                code: 'link/DataCollect/IntegratedQuery',
-                name: '综合查询',
-                owner: 'iot',
-                sortIndex: 3,
-                url: '/iot/link/DataCollect/IntegratedQuery',
-                icon: 'icon-zhilianshebei',
-                showPage: [
-                  'data-collect-channel',
-                  'data-collect-opc',
-                  'data-collector',
-                  'things-collector',
-                ],
-                permissions: [],
-                buttons: [
-                  {
-                    id: 'view',
-                    name: '查看',
-                    permissions: [
-                      {
-                        permission: 'data-collect-channel',
-                        actions: ['query'],
-                      },
-                      {
-                        permission: 'data-collector',
-                        actions: ['query'],
-                      },
-                      {
-                        permission: 'data-collect-opc',
-                        actions: ['query'],
-                      },
-                      {
-                        permission: 'things-collector',
-                        actions: ['query'],
-                      },
-                    ],
-                  },
-                  {
-                    id: 'add',
-                    name: '新增',
-                    permissions: [
-                      {
-                        permission: 'data-collect-channel',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collector',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collect-opc',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'things-collector',
-                        actions: ['save', 'query'],
-                      },
-                    ],
-                  },
-                  {
-                    id: 'update',
-                    name: '编辑',
-                    permissions: [
-                      {
-                        permission: 'data-collect-channel',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collector',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collect-opc',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'things-collector',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'certificate',
-                        actions: ['query'],
-                      },
-                    ],
-                  },
-                  {
-                    id: 'action',
-                    name: '禁用/启用',
-                    permissions: [
-                      {
-                        permission: 'data-collect-channel',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collector',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'data-collect-opc',
-                        actions: ['save', 'query'],
-                      },
-                      {
-                        permission: 'things-collector',
-                        actions: ['save', 'query'],
-                      },
-                    ],
-                  },
-                  {
-                    id: 'delete',
-                    name: '删除',
-                    permissions: [
-                      {
-                        permission: 'data-collect-channel',
-                        actions: ['delete', 'query'],
-                      },
-                      {
-                        permission: 'data-collector',
-                        actions: ['delete', 'query'],
-                      },
-                      {
-                        permission: 'data-collect-opc',
-                        actions: ['delete', 'query'],
-                      },
-                      {
-                        permission: 'things-collector',
-                        actions: ['delete', 'query'],
-                      },
-                    ],
+            buttons: [
+              {
+                id: 'view',
+                name: '查看',
+                permissions: [
+                  {
+                    permission: 'data-collect-channel',
+                    actions: ['query'],
+                  },
+                  {
+                    permission: 'data-collector',
+                    actions: ['query'],
+                  },
+                  {
+                    permission: 'data-collect-opc',
+                    actions: ['query'],
+                  },
+                  {
+                    permission: 'things-collector',
+                    actions: ['query'],
+                  },
+                ],
+              },
+              {
+                id: 'add',
+                name: '新增',
+                permissions: [
+                  {
+                    permission: 'data-collect-channel',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collector',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collect-opc',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'things-collector',
+                    actions: ['save', 'query'],
+                  },
+                ],
+              },
+              {
+                id: 'update',
+                name: '编辑',
+                permissions: [
+                  {
+                    permission: 'data-collect-channel',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collector',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collect-opc',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'things-collector',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'certificate',
+                    actions: ['query'],
+                  },
+                ],
+              },
+              {
+                id: 'action',
+                name: '禁用/启用',
+                permissions: [
+                  {
+                    permission: 'data-collect-channel',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collector',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'data-collect-opc',
+                    actions: ['save', 'query'],
+                  },
+                  {
+                    permission: 'things-collector',
+                    actions: ['save', 'query'],
+                  },
+                ],
+              },
+              {
+                id: 'delete',
+                name: '删除',
+                permissions: [
+                  {
+                    permission: 'data-collect-channel',
+                    actions: ['delete', 'query'],
+                  },
+                  {
+                    permission: 'data-collector',
+                    actions: ['delete', 'query'],
+                  },
+                  {
+                    permission: 'data-collect-opc',
+                    actions: ['delete', 'query'],
+                  },
+                  {
+                    permission: 'things-collector',
+                    actions: ['delete', 'query'],
                   },
                 ],
               },

+ 29 - 4
src/pages/system/Permission/Save/index.tsx

@@ -147,8 +147,18 @@ const Save = (props: Props) => {
               properties: {
                 action: {
                   type: 'string',
-                  'x-decorator': 'Editable',
+                  'x-decorator': 'FormItem',
                   'x-component': 'Input',
+                  'x-validator': [
+                    {
+                      required: true,
+                      message: '请输入操作类型',
+                    },
+                    {
+                      max: 64,
+                      message: '最多可输入64个字符',
+                    },
+                  ],
                 },
               },
             },
@@ -165,9 +175,18 @@ const Save = (props: Props) => {
               properties: {
                 name: {
                   type: 'string',
-
-                  'x-decorator': 'Editable',
+                  'x-decorator': 'FormItem',
                   'x-component': 'Input',
+                  'x-validator': [
+                    {
+                      required: true,
+                      message: '请输入名称',
+                    },
+                    {
+                      max: 64,
+                      message: '最多可输入64个字符',
+                    },
+                  ],
                 },
               },
             },
@@ -184,8 +203,14 @@ const Save = (props: Props) => {
               properties: {
                 describe: {
                   type: 'string',
-                  'x-decorator': 'Editable',
+                  'x-decorator': 'FormItem',
                   'x-component': 'Input',
+                  'x-validator': [
+                    {
+                      max: 64,
+                      message: '最多可输入64个字符',
+                    },
+                  ],
                 },
               },
             },

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

@@ -120,7 +120,7 @@ const Permission: React.FC = observer(() => {
       fixed: 'left',
       width: '30%',
       // sorter: true,
-      defaultSortOrder: 'ascend',
+      // defaultSortOrder: 'ascend',
     },
     {
       title: intl.formatMessage({