xieyonghong 4 anni fa
parent
commit
a1cf6ca487
27 ha cambiato i file con 302 aggiunte e 210 eliminazioni
  1. BIN
      public/images/alarm/alarm-config.png
  2. 12 0
      src/components/FInputGroup/index.tsx
  3. 1 0
      src/components/FInputGroup/style.ts
  4. 3 3
      src/components/ProTableCard/CardItems/AlarmConfig.tsx
  5. 1 1
      src/components/ProTableCard/TableCard.tsx
  6. 7 1
      src/pages/device/Instance/Detail/Config/index.tsx
  7. 2 2
      src/pages/device/Instance/Detail/Diagnose/Status/index.tsx
  8. 2 2
      src/pages/device/Instance/Detail/Diagnose/Status/model.ts
  9. 3 1
      src/pages/device/Instance/Detail/MetadataLog/Property/index.tsx
  10. 24 4
      src/pages/device/Product/index.tsx
  11. 18 1
      src/pages/device/components/Metadata/Cat/index.tsx
  12. 1 1
      src/pages/link/AccessConfig/Detail/Access/index.tsx
  13. 1 1
      src/pages/notice/Config/BindUser/index.tsx
  14. 5 4
      src/pages/notice/Template/Debug/index.tsx
  15. 4 4
      src/pages/notice/Template/Detail/index.tsx
  16. 2 2
      src/pages/rule-engine/Alarm/Configuration/Save/index.tsx
  17. 27 15
      src/pages/rule-engine/Alarm/Configuration/index.tsx
  18. 8 6
      src/pages/rule-engine/Alarm/Log/Detail/Info.tsx
  19. 8 2
      src/pages/rule-engine/Alarm/Log/Detail/index.tsx
  20. 1 0
      src/pages/rule-engine/Alarm/Log/SolveComponent/index.tsx
  21. 63 17
      src/pages/rule-engine/Alarm/Log/TabComponent/index.less
  22. 43 27
      src/pages/rule-engine/Alarm/Log/TabComponent/index.tsx
  23. 2 0
      src/pages/rule-engine/Alarm/Log/index.tsx
  24. 6 1
      src/pages/rule-engine/Alarm/Log/model.ts
  25. 56 114
      src/pages/rule-engine/Scene/TriggerTerm/index.tsx
  26. 1 0
      src/utils/menu/router.ts
  27. 1 1
      src/utils/util.ts

BIN
public/images/alarm/alarm-config.png


+ 12 - 0
src/components/FInputGroup/index.tsx

@@ -0,0 +1,12 @@
+import { Input } from 'antd';
+import { GroupProps } from 'antd/lib/input';
+import React from 'react';
+
+const InputGroup = Input.Group;
+
+export const FInputGroup: React.FC<GroupProps> = (props) => {
+  return React.createElement(InputGroup, {
+    ...props,
+  });
+};
+export default FInputGroup;

+ 1 - 0
src/components/FInputGroup/style.ts

@@ -0,0 +1 @@
+import 'antd/lib/input/style/index';

+ 3 - 3
src/components/ProTableCard/CardItems/AlarmConfig.tsx

@@ -10,15 +10,15 @@ export interface AlarmConfigProps extends ConfigurationItem {
   avatarSize?: number;
   avatarSize?: number;
 }
 }
 
 
-export const aliyunSms = require('/public/images/notice/sms.png');
+export const aliyunSms = require('/public/images/alarm/alarm-config.png');
 
 
 export default (props: AlarmConfigProps) => {
 export default (props: AlarmConfigProps) => {
   return (
   return (
     <TableCard
     <TableCard
       actions={props.actions}
       actions={props.actions}
       detail={props.detail}
       detail={props.detail}
-      status={props.state.value}
-      statusText={props.state.text}
+      status={props.state?.value}
+      statusText={props.state?.text}
       statusNames={{
       statusNames={{
         enabled: StatusColorEnum.success,
         enabled: StatusColorEnum.success,
         disabled: StatusColorEnum.error,
         disabled: StatusColorEnum.error,

+ 1 - 1
src/components/ProTableCard/TableCard.tsx

@@ -1,8 +1,8 @@
 import React, { useState } from 'react';
 import React, { useState } from 'react';
 import classNames from 'classnames';
 import classNames from 'classnames';
 import { BadgeStatus } from '@/components';
 import { BadgeStatus } from '@/components';
-import { StatusColorEnum } from '@/components/BadgeStatus';
 import type { StatusColorType } from '@/components/BadgeStatus';
 import type { StatusColorType } from '@/components/BadgeStatus';
+import { StatusColorEnum } from '@/components/BadgeStatus';
 import './index.less';
 import './index.less';
 
 
 export interface TableCardProps {
 export interface TableCardProps {

+ 7 - 1
src/pages/device/Instance/Detail/Config/index.tsx

@@ -145,7 +145,13 @@ const Config = () => {
       </div>
       </div>
       <div>
       <div>
         {(metadata || []).map((i) => (
         {(metadata || []).map((i) => (
-          <Descriptions size="small" column={3} key={i.name} bordered title={<h4>{i.name}</h4>}>
+          <Descriptions
+            size="small"
+            column={3}
+            key={i.name}
+            bordered
+            title={<h4 style={{ fontSize: 15 }}>{i.name}</h4>}
+          >
             {(i?.properties || []).map((item: any) => (
             {(i?.properties || []).map((item: any) => (
               <Descriptions.Item
               <Descriptions.Item
                 span={1}
                 span={1}

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

@@ -161,10 +161,10 @@ const Status = observer((props: Props) => {
       } else {
       } else {
         service.queryProductState(InstanceModel.detail?.productId || '').then((resp) => {
         service.queryProductState(InstanceModel.detail?.productId || '').then((resp) => {
           if (resp.status === 200) {
           if (resp.status === 200) {
-            DiagnoseStatusModel.product = resp.result;
             if (resp.result.accessId) {
             if (resp.result.accessId) {
               service.queryGatewayState(resp.result.accessId).then((response: any) => {
               service.queryGatewayState(resp.result.accessId).then((response: any) => {
                 if (response.status === 200) {
                 if (response.status === 200) {
+                  DiagnoseStatusModel.gateway = response.result;
                   const product: any = resp.result;
                   const product: any = resp.result;
                   const address = response.result?.channelInfo?.addresses || [];
                   const address = response.result?.channelInfo?.addresses || [];
                   const _label = address.some((i: any) => i.health === -1);
                   const _label = address.some((i: any) => i.health === -1);
@@ -212,7 +212,7 @@ const Status = observer((props: Props) => {
                                         title="确认启用"
                                         title="确认启用"
                                         onConfirm={async () => {
                                         onConfirm={async () => {
                                           const res = await service.startNetwork(
                                           const res = await service.startNetwork(
-                                            DiagnoseStatusModel.product?.channelId,
+                                            DiagnoseStatusModel.gateway?.channelId,
                                           );
                                           );
                                           if (res.status === 200) {
                                           if (res.status === 200) {
                                             message.success('操作成功!');
                                             message.success('操作成功!');

+ 2 - 2
src/pages/device/Instance/Detail/Diagnose/Status/model.ts

@@ -27,7 +27,7 @@ export const DiagnoseStatusModel = model<{
   };
   };
   list: ListProps[];
   list: ListProps[];
   model: boolean;
   model: boolean;
-  product: any;
+  gateway: any;
 }>({
 }>({
   status: {
   status: {
     config: {
     config: {
@@ -88,5 +88,5 @@ export const DiagnoseStatusModel = model<{
     },
     },
   ],
   ],
   model: true,
   model: true,
-  product: {},
+  gateway: {},
 });
 });

+ 3 - 1
src/pages/device/Instance/Detail/MetadataLog/Property/index.tsx

@@ -63,7 +63,7 @@ const PropertyLog = (props: Props) => {
           pageIndex: 0,
           pageIndex: 0,
         },
         },
         start,
         start,
-        end,
+        new Date().getTime(),
       );
       );
     }
     }
   }, [visible]);
   }, [visible]);
@@ -75,6 +75,7 @@ const PropertyLog = (props: Props) => {
       title="详情"
       title="详情"
       visible={visible}
       visible={visible}
       onCancel={() => close()}
       onCancel={() => close()}
+      onOk={() => close()}
       width="45vw"
       width="45vw"
     >
     >
       <div style={{ marginBottom: '20px' }}>
       <div style={{ marginBottom: '20px' }}>
@@ -106,6 +107,7 @@ const PropertyLog = (props: Props) => {
                 et,
                 et,
               );
               );
             }}
             }}
+            style={{ minWidth: 220 }}
           >
           >
             <Radio.Button value="today">今日</Radio.Button>
             <Radio.Button value="today">今日</Radio.Button>
             <Radio.Button value="week">近一周</Radio.Button>
             <Radio.Button value="week">近一周</Radio.Button>

+ 24 - 4
src/pages/device/Product/index.tsx

@@ -24,6 +24,7 @@ import ProductCard from '@/components/ProTableCard/CardItems/product';
 import { downloadObject } from '@/utils/util';
 import { downloadObject } from '@/utils/util';
 import { service as categoryService } from '@/pages/device/Category';
 import { service as categoryService } from '@/pages/device/Category';
 import { service as deptService } from '@/pages/system/Department';
 import { service as deptService } from '@/pages/system/Department';
+import { omit } from 'lodash';
 
 
 export const service = new Service('device-product');
 export const service = new Service('device-product');
 export const statusMap = {
 export const statusMap = {
@@ -113,6 +114,7 @@ const Product = observer(() => {
         productModel.current = record;
         productModel.current = record;
         history.push(`${getMenuPathByParams(MENUS_CODE['device/Product/Detail'], record.id)}`);
         history.push(`${getMenuPathByParams(MENUS_CODE['device/Product/Detail'], record.id)}`);
       }}
       }}
+      key="view"
       style={{ padding: 0 }}
       style={{ padding: 0 }}
     >
     >
       <Tooltip
       <Tooltip
@@ -146,6 +148,7 @@ const Product = observer(() => {
     <PermissionButton
     <PermissionButton
       isPermission={permission.export}
       isPermission={permission.export}
       type={'link'}
       type={'link'}
+      key="download"
       style={{ padding: 0 }}
       style={{ padding: 0 }}
       tooltip={{
       tooltip={{
         title: intl.formatMessage({
         title: intl.formatMessage({
@@ -153,9 +156,17 @@ const Product = observer(() => {
           defaultMessage: '下载',
           defaultMessage: '下载',
         }),
         }),
       }}
       }}
-      onClick={async () => {
+      onClick={() => {
+        const extra = omit(record, [
+          'transportProtocol',
+          'protocolName',
+          'accessId',
+          'accessName',
+          'accessProvider',
+          'messageProtocol',
+        ]);
         downloadObject(
         downloadObject(
-          record,
+          extra,
           intl.formatMessage({
           intl.formatMessage({
             id: 'pages.device.product',
             id: 'pages.device.product',
             defaultMessage: '产品',
             defaultMessage: '产品',
@@ -167,6 +178,7 @@ const Product = observer(() => {
       <DownloadOutlined />
       <DownloadOutlined />
     </PermissionButton>,
     </PermissionButton>,
     <PermissionButton
     <PermissionButton
+      key="action"
       popConfirm={{
       popConfirm={{
         title: intl.formatMessage({
         title: intl.formatMessage({
           id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}.tips`,
           id: `pages.data.option.${record.state ? 'disabled' : 'enabled'}.tips`,
@@ -496,9 +508,17 @@ const Product = observer(() => {
                 type={'link'}
                 type={'link'}
                 key={'download'}
                 key={'download'}
                 style={{ padding: 0 }}
                 style={{ padding: 0 }}
-                onClick={async () => {
+                onClick={() => {
+                  const extra = omit(record, [
+                    'transportProtocol',
+                    'protocolName',
+                    'accessId',
+                    'accessName',
+                    'accessProvider',
+                    'messageProtocol',
+                  ]);
                   downloadObject(
                   downloadObject(
-                    record,
+                    extra,
                     intl.formatMessage({
                     intl.formatMessage({
                       id: 'pages.device.product',
                       id: 'pages.device.product',
                       defaultMessage: '产品',
                       defaultMessage: '产品',

+ 18 - 1
src/pages/device/components/Metadata/Cat/index.tsx

@@ -1,4 +1,4 @@
-import { Drawer, Tabs } from 'antd';
+import { Button, Drawer, message, Space, Tabs } from 'antd';
 import { useEffect, useState } from 'react';
 import { useEffect, useState } from 'react';
 import { productModel, service } from '@/pages/device/Product';
 import { productModel, service } from '@/pages/device/Product';
 import MonacoEditor from 'react-monaco-editor';
 import MonacoEditor from 'react-monaco-editor';
@@ -6,6 +6,7 @@ import { observer } from '@formily/react';
 import { InstanceModel } from '@/pages/device/Instance';
 import { InstanceModel } from '@/pages/device/Instance';
 import { useLocation } from 'umi';
 import { useLocation } from 'umi';
 import InstanceService from '@/pages/device/Instance/service';
 import InstanceService from '@/pages/device/Instance/service';
+import { downloadObject } from '@/utils/util';
 
 
 interface Props {
 interface Props {
   visible: boolean;
   visible: boolean;
@@ -63,6 +64,22 @@ const Cat = observer((props: Props) => {
       title="查看物模型"
       title="查看物模型"
       onClose={() => props.close()}
       onClose={() => props.close()}
       visible={props.visible}
       visible={props.visible}
+      extra={
+        <Space>
+          <Button
+            type="primary"
+            onClick={async () => {
+              try {
+                downloadObject(JSON.parse(value), `设备-物模型`);
+              } catch (e) {
+                message.error('物模型格式错误!');
+              }
+            }}
+          >
+            导出模型文件
+          </Button>
+        </Space>
+      }
     >
     >
       <div style={{ background: 'rgb(236, 237, 238)' }}>
       <div style={{ background: 'rgb(236, 237, 238)' }}>
         <p style={{ padding: 10 }}>
         <p style={{ padding: 10 }}>

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

@@ -61,7 +61,7 @@ const Access = (props: Props) => {
   ProcotoleMapping.set('mqtt-client-gateway', 'MQTT');
   ProcotoleMapping.set('mqtt-client-gateway', 'MQTT');
   ProcotoleMapping.set('mqtt-server-gateway', 'MQTT');
   ProcotoleMapping.set('mqtt-server-gateway', 'MQTT');
   ProcotoleMapping.set('tcp-server-gateway', 'TCP');
   ProcotoleMapping.set('tcp-server-gateway', 'TCP');
-  ProcotoleMapping.set('child-device', 'Gateway');
+  ProcotoleMapping.set('child-device', '');
 
 
   const queryNetworkList = (id: string, params?: any) => {
   const queryNetworkList = (id: string, params?: any) => {
     service.getNetworkList(MetworkTypeMapping.get(id), params).then((resp) => {
     service.getNetworkList(MetworkTypeMapping.get(id), params).then((resp) => {

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

@@ -37,7 +37,7 @@ const BindUser = (props: Props) => {
   };
   };
 
 
   useEffect(() => {
   useEffect(() => {
-    if (props.data?.id) {
+    if (props.data?.thirdPartyUserId) {
       getUsers(props.data.id);
       getUsers(props.data.id);
     }
     }
   }, [props.data]);
   }, [props.data]);

+ 5 - 4
src/pages/notice/Template/Debug/index.tsx

@@ -203,9 +203,10 @@ const Debug = observer(() => {
     const data: { configId: string; variableDefinitions: any } = await form.submit();
     const data: { configId: string; variableDefinitions: any } = await form.submit();
     // 应该取选择的配置信息
     // 应该取选择的配置信息
     if (!state.current) return;
     if (!state.current) return;
-    const resp = await service.debug(data.configId, state?.current.id, {
-      template: state.current,
-      context: data.variableDefinitions?.reduce(
+    const resp = await service.debug(
+      data.configId,
+      state?.current.id,
+      data.variableDefinitions?.reduce(
         (previousValue: any, currentValue: { id: any; value: any }) => {
         (previousValue: any, currentValue: { id: any; value: any }) => {
           return {
           return {
             ...previousValue,
             ...previousValue,
@@ -214,7 +215,7 @@ const Debug = observer(() => {
         },
         },
         {},
         {},
       ),
       ),
-    });
+    );
     if (resp.status === 200) {
     if (resp.status === 200) {
       message.success('操作成功!');
       message.success('操作成功!');
     }
     }

+ 4 - 4
src/pages/notice/Template/Detail/index.tsx

@@ -265,7 +265,7 @@ const Detail = observer(() => {
                   : {
                   : {
                       id: item,
                       id: item,
                       type: 'string',
                       type: 'string',
-                      format: 's%',
+                      format: '%s',
                     },
                     },
               );
               );
               form1.setValuesIn('variableDefinitions', _result);
               form1.setValuesIn('variableDefinitions', _result);
@@ -313,7 +313,7 @@ const Detail = observer(() => {
                   : {
                   : {
                       id: item,
                       id: item,
                       type: 'string',
                       type: 'string',
-                      format: 's%',
+                      format: '%s',
                     },
                     },
               );
               );
               form1.setValuesIn('variableDefinitions', _result);
               form1.setValuesIn('variableDefinitions', _result);
@@ -354,7 +354,7 @@ const Detail = observer(() => {
               case 'string':
               case 'string':
                 format.setComponent(PreviewText.Input);
                 format.setComponent(PreviewText.Input);
                 if (fieldModified) {
                 if (fieldModified) {
-                  format.setValue('s%');
+                  format.setValue('%s');
                 }
                 }
                 break;
                 break;
               case 'number':
               case 'number':
@@ -1200,7 +1200,7 @@ const Detail = observer(() => {
             column2: {
             column2: {
               type: 'void',
               type: 'void',
               'x-component': 'ArrayTable.Column',
               'x-component': 'ArrayTable.Column',
-              'x-component-props': { title: '名称' },
+              'x-component-props': { title: '名称', width: '120px' },
               properties: {
               properties: {
                 name: {
                 name: {
                   type: 'string',
                   type: 'string',

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

@@ -3,7 +3,7 @@ import { useMemo } from 'react';
 import { createForm } from '@formily/core';
 import { createForm } from '@formily/core';
 import { createSchemaField } from '@formily/react';
 import { createSchemaField } from '@formily/react';
 import { Form, FormGrid, FormItem, Input, Radio, Select } from '@formily/antd';
 import { Form, FormGrid, FormItem, Input, Radio, Select } from '@formily/antd';
-import { ISchema } from '@formily/json-schema';
+import type { ISchema } from '@formily/json-schema';
 import { PermissionButton } from '@/components';
 import { PermissionButton } from '@/components';
 import { PlusOutlined } from '@ant-design/icons';
 import { PlusOutlined } from '@ant-design/icons';
 import Service from '@/pages/rule-engine/Alarm/Configuration/service';
 import Service from '@/pages/rule-engine/Alarm/Configuration/service';
@@ -213,7 +213,7 @@ const Save = (props: Props) => {
       visible={visible}
       visible={visible}
       onOk={handleSave}
       onOk={handleSave}
       onCancel={() => close()}
       onCancel={() => close()}
-      title="新增告警"
+      title={`${props.data ? '编辑' : '新增'}告警`}
     >
     >
       <Form className={styles.form} form={form} layout="vertical">
       <Form className={styles.form} form={form} layout="vertical">
         <SchemaField
         <SchemaField

+ 27 - 15
src/pages/rule-engine/Alarm/Configuration/index.tsx

@@ -24,6 +24,7 @@ const Configuration = () => {
   const intl = useIntl();
   const intl = useIntl();
   const [visible, setVisible] = useState<boolean>(false);
   const [visible, setVisible] = useState<boolean>(false);
   const actionRef = useRef<ActionType>();
   const actionRef = useRef<ActionType>();
+  const { permission } = PermissionButton.usePermission('rule-engine/Alarm/Configuration');
 
 
   const [current, setCurrent] = useState<any>();
   const [current, setCurrent] = useState<any>();
   const columns: ProColumns<ConfigurationItem>[] = [
   const columns: ProColumns<ConfigurationItem>[] = [
@@ -64,8 +65,13 @@ const Configuration = () => {
             key="trigger"
             key="trigger"
             type="link"
             type="link"
             style={{ padding: 0 }}
             style={{ padding: 0 }}
-            isPermission={true}
+            isPermission={permission.tigger}
+            tooltip={{
+              title: record.state?.value === 'disabled' ? '未启用,不能手动触发' : '',
+            }}
+            disabled={record.state?.value === 'disabled'}
             popConfirm={{
             popConfirm={{
+              disabled: record.state?.value === 'disabled',
               title: '确认手动触发?',
               title: '确认手动触发?',
               onConfirm: async () => {
               onConfirm: async () => {
                 await service._execute(record.sceneId);
                 await service._execute(record.sceneId);
@@ -83,7 +89,7 @@ const Configuration = () => {
           </PermissionButton>
           </PermissionButton>
         ),
         ),
         <PermissionButton
         <PermissionButton
-          isPermission={true}
+          isPermission={permission.update}
           key="edit"
           key="edit"
           style={{ padding: 0 }}
           style={{ padding: 0 }}
           tooltip={{
           tooltip={{
@@ -101,7 +107,7 @@ const Configuration = () => {
           <EditOutlined />
           <EditOutlined />
         </PermissionButton>,
         </PermissionButton>,
         <PermissionButton
         <PermissionButton
-          isPermission={true}
+          isPermission={permission.action}
           key="action"
           key="action"
           style={{ padding: 0 }}
           style={{ padding: 0 }}
           popConfirm={{
           popConfirm={{
@@ -140,19 +146,17 @@ const Configuration = () => {
         </PermissionButton>,
         </PermissionButton>,
         <PermissionButton
         <PermissionButton
           type="link"
           type="link"
-          isPermission={true}
+          isPermission={permission.delete}
           key="delete"
           key="delete"
           disabled={record.state?.value !== 'disabled'}
           disabled={record.state?.value !== 'disabled'}
           style={{ padding: 0 }}
           style={{ padding: 0 }}
           popConfirm={{
           popConfirm={{
+            disabled: record.state?.value !== 'disabled',
             title: '确认删除?',
             title: '确认删除?',
             onConfirm: () => service.remove(record.id),
             onConfirm: () => service.remove(record.id),
           }}
           }}
           tooltip={{
           tooltip={{
-            title: intl.formatMessage({
-              id: 'pages.data.option.remove',
-              defaultMessage: '删除',
-            }),
+            title: record.state?.value === 'disabled' ? '删除' : '已启用,不能删除',
           }}
           }}
         >
         >
           <DeleteOutlined />
           <DeleteOutlined />
@@ -178,7 +182,9 @@ const Configuration = () => {
         search={false}
         search={false}
         params={param}
         params={param}
         columns={columns}
         columns={columns}
-        request={(params) => service.query(params)}
+        request={(params) =>
+          service.query({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
+        }
         gridColumn={3}
         gridColumn={3}
         cardRender={(record) => (
         cardRender={(record) => (
           <AlarmConfig
           <AlarmConfig
@@ -188,9 +194,14 @@ const Configuration = () => {
                 <PermissionButton
                 <PermissionButton
                   key="trigger"
                   key="trigger"
                   type="link"
                   type="link"
-                  isPermission={true}
+                  tooltip={{
+                    title: record.state?.value === 'disabled' ? '未启用,不能手动触发' : '',
+                  }}
+                  disabled={record.state?.value === 'disabled'}
+                  isPermission={permission.tigger}
                   popConfirm={{
                   popConfirm={{
                     title: '确认手动触发?',
                     title: '确认手动触发?',
+                    disabled: record.state?.value === 'disabled',
                     onConfirm: async () => {
                     onConfirm: async () => {
                       await service._execute(record.sceneId);
                       await service._execute(record.sceneId);
                       message.success(
                       message.success(
@@ -208,7 +219,7 @@ const Configuration = () => {
                 </PermissionButton>
                 </PermissionButton>
               ) : null,
               ) : null,
               <PermissionButton
               <PermissionButton
-                isPermission={true}
+                isPermission={permission.update}
                 key="edit"
                 key="edit"
                 type="link"
                 type="link"
                 onClick={() => {
                 onClick={() => {
@@ -220,7 +231,7 @@ const Configuration = () => {
                 编辑
                 编辑
               </PermissionButton>,
               </PermissionButton>,
               <PermissionButton
               <PermissionButton
-                isPermission={true}
+                isPermission={permission.action}
                 style={{ padding: 0 }}
                 style={{ padding: 0 }}
                 popConfirm={{
                 popConfirm={{
                   title: intl.formatMessage({
                   title: intl.formatMessage({
@@ -265,17 +276,18 @@ const Configuration = () => {
               <PermissionButton
               <PermissionButton
                 type="link"
                 type="link"
                 tooltip={{
                 tooltip={{
-                  title: '删除',
+                  title: record.state?.value === 'disabled' ? '删除' : '已启用,不能删除',
                 }}
                 }}
                 disabled={record.state?.value !== 'disabled'}
                 disabled={record.state?.value !== 'disabled'}
                 popConfirm={{
                 popConfirm={{
+                  disabled: record.state?.value !== 'disabled',
                   title: '确认删除?',
                   title: '确认删除?',
                   onConfirm: async () => {
                   onConfirm: async () => {
                     await service.remove(record.id);
                     await service.remove(record.id);
                     actionRef.current?.reset?.();
                     actionRef.current?.reset?.();
                   },
                   },
                 }}
                 }}
-                isPermission={true}
+                isPermission={permission.delete}
                 key="delete"
                 key="delete"
               >
               >
                 <DeleteOutlined />
                 <DeleteOutlined />
@@ -286,7 +298,7 @@ const Configuration = () => {
         headerTitle={
         headerTitle={
           <Space>
           <Space>
             <PermissionButton
             <PermissionButton
-              isPermission={true}
+              isPermission={permission.add}
               onClick={() => {
               onClick={() => {
                 setCurrent(undefined);
                 setCurrent(undefined);
                 setVisible(true);
                 setVisible(true);

+ 8 - 6
src/pages/rule-engine/Alarm/Log/Detail/Info.tsx

@@ -1,6 +1,7 @@
 import { Descriptions, Modal } from 'antd';
 import { Descriptions, Modal } from 'antd';
 import { useEffect, useState } from 'react';
 import { useEffect, useState } from 'react';
 import moment from 'moment';
 import moment from 'moment';
+import { Store } from 'jetlinks-store';
 
 
 interface Props {
 interface Props {
   data: Partial<AlarmLogHistoryItem>;
   data: Partial<AlarmLogHistoryItem>;
@@ -20,27 +21,28 @@ const Info = (props: Props) => {
         {data.targetType === 'device' && (
         {data.targetType === 'device' && (
           <>
           <>
             <Descriptions.Item label="告警设备" span={1}>
             <Descriptions.Item label="告警设备" span={1}>
-              {data?.targetName}
+              {data?.targetName || '--'}
             </Descriptions.Item>
             </Descriptions.Item>
             <Descriptions.Item label="设备ID" span={1}>
             <Descriptions.Item label="设备ID" span={1}>
-              {data?.targetId}
+              {data?.targetId || '--'}
             </Descriptions.Item>
             </Descriptions.Item>
           </>
           </>
         )}
         )}
         <Descriptions.Item label="告警名称" span={1}>
         <Descriptions.Item label="告警名称" span={1}>
-          {data?.alarmConfigName}
+          {data?.alarmConfigName || '--'}
         </Descriptions.Item>
         </Descriptions.Item>
         <Descriptions.Item label="告警时间" span={1}>
         <Descriptions.Item label="告警时间" span={1}>
           {moment(data?.alarmTime).format('YYYY-MM-DD HH:mm:ss')}
           {moment(data?.alarmTime).format('YYYY-MM-DD HH:mm:ss')}
         </Descriptions.Item>
         </Descriptions.Item>
         <Descriptions.Item label="告警级别" span={1}>
         <Descriptions.Item label="告警级别" span={1}>
-          {data?.level}
+          {(Store.get('default-level') || []).find((item: any) => item?.level === data?.level)
+            ?.title || data?.level}
         </Descriptions.Item>
         </Descriptions.Item>
         <Descriptions.Item label="告警说明" span={1}>
         <Descriptions.Item label="告警说明" span={1}>
-          {data?.description}
+          {data?.description || '--'}
         </Descriptions.Item>
         </Descriptions.Item>
         <Descriptions.Item label="告警流水" span={2}>
         <Descriptions.Item label="告警流水" span={2}>
-          {data?.alarmInfo}
+          {data?.alarmInfo || '--'}
         </Descriptions.Item>
         </Descriptions.Item>
       </Descriptions>
       </Descriptions>
     </Modal>
     </Modal>

+ 8 - 2
src/pages/rule-engine/Alarm/Log/Detail/index.tsx

@@ -40,20 +40,25 @@ const Detail = observer(() => {
     {
     {
       dataIndex: 'alarmTime',
       dataIndex: 'alarmTime',
       title: '告警时间',
       title: '告警时间',
+      valueType: 'dateTime',
       render: (text: any) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>,
       render: (text: any) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>,
     },
     },
     {
     {
       dataIndex: 'alarmConfigName',
       dataIndex: 'alarmConfigName',
       title: '告警名称',
       title: '告警名称',
+      hideInSearch: true,
     },
     },
     {
     {
       dataIndex: 'description',
       dataIndex: 'description',
       title: '说明',
       title: '说明',
+      hideInSearch: true,
     },
     },
     {
     {
       dataIndex: 'action',
       dataIndex: 'action',
       title: '操作',
       title: '操作',
-      render: (record: any) => (
+      hideInSearch: true,
+      valueType: 'option',
+      render: (_: any, record: any) => (
         <Button type="link">
         <Button type="link">
           <SearchOutlined
           <SearchOutlined
             onClick={() => {
             onClick={() => {
@@ -74,9 +79,10 @@ const Detail = observer(() => {
           initColumns.splice(2, 0, {
           initColumns.splice(2, 0, {
             dataIndex: 'targetName',
             dataIndex: 'targetName',
             title: '告警设备',
             title: '告警设备',
+            hideInSearch: true,
           });
           });
         }
         }
-        AlarmLogModel.columns = initColumns;
+        AlarmLogModel.columns = [...initColumns];
       }
       }
     });
     });
   }, [params.id]);
   }, [params.id]);

+ 1 - 0
src/pages/rule-engine/Alarm/Log/SolveComponent/index.tsx

@@ -26,6 +26,7 @@ const SolveComponent = (props: Props) => {
         form={form}
         form={form}
         onFinish={async (values: any) => {
         onFinish={async (values: any) => {
           const resp = await service.handleLog(data?.id || '', {
           const resp = await service.handleLog(data?.id || '', {
+            id: data?.id || '',
             describe: values.describe,
             describe: values.describe,
             type: 'user',
             type: 'user',
             state: 'normal',
             state: 'normal',

+ 63 - 17
src/pages/rule-engine/Alarm/Log/TabComponent/index.less

@@ -1,5 +1,7 @@
 @import '~antd/es/style/themes/default.less';
 @import '~antd/es/style/themes/default.less';
 
 
+@alarm-log-padding-left: 60px;
+
 .ellipsis {
 .ellipsis {
   width: 100%;
   width: 100%;
   overflow: hidden;
   overflow: hidden;
@@ -11,7 +13,6 @@
   .alarm-log-item {
   .alarm-log-item {
     display: flex;
     display: flex;
     margin-bottom: 20px;
     margin-bottom: 20px;
-    box-shadow: 0 2px 16px rgba(0, 0, 0, 0.1);
 
 
     .alarm-log-title {
     .alarm-log-title {
       position: relative;
       position: relative;
@@ -52,32 +53,43 @@
       background: url('/images/alarm/background.png') no-repeat;
       background: url('/images/alarm/background.png') no-repeat;
       background-size: 100% 100%;
       background-size: 100% 100%;
 
 
-      .alarm-log-image {
+      .alarm-log-data {
         display: flex;
         display: flex;
         align-items: center;
         align-items: center;
+        min-width: 60%;
+        max-width: 100%;
 
 
-        .alarm-type {
-          max-width: 120px;
-          padding-right: 50px;
+        .alarm-log-image {
+          display: flex;
+          align-items: center;
+          padding-right: @alarm-log-padding-left;
           border-right: 1px solid rgba(0, 0, 0, 0.09);
           border-right: 1px solid rgba(0, 0, 0, 0.09);
-          .name {
-            color: #000;
-            font-size: 18px;
-          }
 
 
-          .text {
-            margin-top: 8px;
-            color: #666;
-            font-size: 14px;
-            .ellipsis();
+          .alarm-type {
+            max-width: 120px;
+
+            .name {
+              color: #000;
+              font-size: 18px;
+            }
+
+            .text {
+              margin-top: 8px;
+              color: #666;
+              font-size: 14px;
+              .ellipsis();
+            }
           }
           }
         }
         }
         .alarm-log-right {
         .alarm-log-right {
           display: flex;
           display: flex;
-          padding-left: 40px;
+          justify-content: space-between;
+          width: 50%;
+          padding-left: @alarm-log-padding-left;
+
           .alarm-log-time {
           .alarm-log-time {
             max-width: 165px;
             max-width: 165px;
-            margin: 0 10px;
+
             .log-title {
             .log-title {
               margin-top: 8px;
               margin-top: 8px;
               color: #666;
               color: #666;
@@ -91,9 +103,12 @@
               .ellipsis();
               .ellipsis();
             }
             }
           }
           }
+
+          .alarm-log-status {
+            margin-left: @alarm-log-padding-left;
+          }
         }
         }
       }
       }
-
       .alarm-log-actions {
       .alarm-log-actions {
         .alarm-log-action {
         .alarm-log-action {
           display: flex;
           display: flex;
@@ -122,14 +137,45 @@
             }
             }
           }
           }
         }
         }
+
         .alarm-log-action:hover {
         .alarm-log-action:hover {
           background-color: @primary-color;
           background-color: @primary-color;
+
           .icon,
           .icon,
           div {
           div {
             color: #fff;
             color: #fff;
           }
           }
         }
         }
+        .alarm-log-disabled {
+          display: flex;
+          justify-content: center;
+          width: 72px;
+          height: 72px;
+          border: 1px solid rgba(0, 0, 0, 0.25);
+          .btn {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+            width: 72px;
+            height: 72px;
+            .icon {
+              margin-bottom: 5px;
+              color: rgba(0, 0, 0, 0.25);
+              font-size: 25px;
+            }
+
+            div {
+              color: rgba(0, 0, 0, 0.25);
+              font-size: 12px;
+            }
+          }
+        }
       }
       }
     }
     }
   }
   }
+
+  .alarm-log-item:hover {
+    box-shadow: 0 2px 16px rgba(0, 0, 0, 0.1);
+  }
 }
 }

+ 43 - 27
src/pages/rule-engine/Alarm/Log/TabComponent/index.tsx

@@ -1,7 +1,7 @@
 import SearchComponent from '@/components/SearchComponent';
 import SearchComponent from '@/components/SearchComponent';
 import { FileFilled, FileTextFilled, ToolFilled } from '@ant-design/icons';
 import { FileFilled, FileTextFilled, ToolFilled } from '@ant-design/icons';
 import type { ProColumns } from '@jetlinks/pro-table';
 import type { ProColumns } from '@jetlinks/pro-table';
-import { Badge, Button, Card, Col, Empty, Pagination, Row, Space } from 'antd';
+import { Badge, Button, Card, Col, Empty, Pagination, Row, Space, Tooltip } from 'antd';
 import { useEffect, useState } from 'react';
 import { useEffect, useState } from 'react';
 import './index.less';
 import './index.less';
 import SolveComponent from '../SolveComponent';
 import SolveComponent from '../SolveComponent';
@@ -12,6 +12,8 @@ import { observer } from '@formily/reactive-react';
 import { service } from '@/pages/rule-engine/Alarm/Log';
 import { service } from '@/pages/rule-engine/Alarm/Log';
 import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { useHistory } from 'umi';
 import { useHistory } from 'umi';
+import PermissionButton from '@/components/PermissionButton';
+import classNames from 'classnames';
 
 
 interface Props {
 interface Props {
   type: string;
   type: string;
@@ -37,6 +39,7 @@ colorMap.set(4, '#999999');
 colorMap.set(5, '#C4C4C4');
 colorMap.set(5, '#C4C4C4');
 
 
 const TabComponent = observer((props: Props) => {
 const TabComponent = observer((props: Props) => {
+  const { permission } = PermissionButton.usePermission('rule-engine/Alarm/Log');
   const columns: ProColumns<any>[] = [
   const columns: ProColumns<any>[] = [
     {
     {
       title: '名称',
       title: '名称',
@@ -155,17 +158,21 @@ const TabComponent = observer((props: Props) => {
                     <div className="alarm-log-title-text">{item.alarmName}</div>
                     <div className="alarm-log-title-text">{item.alarmName}</div>
                   </div>
                   </div>
                   <div className="alarm-log-content">
                   <div className="alarm-log-content">
-                    <div className="alarm-log-image">
-                      <img
-                        width={88}
-                        height={88}
-                        src={imgMap.get(props.type)}
-                        alt={''}
-                        style={{ marginRight: 20 }}
-                      />
-                      <div className="alarm-type">
-                        <div className="name">{titleMap.get(item.targetType)}</div>
-                        <div className="text">{item.targetName}</div>
+                    <div className="alarm-log-data">
+                      <div className="alarm-log-image">
+                        <img
+                          width={88}
+                          height={88}
+                          src={imgMap.get(props.type)}
+                          alt={''}
+                          style={{ marginRight: 20 }}
+                        />
+                        <div className="alarm-type">
+                          <div className="name">{titleMap.get(item.targetType)}</div>
+                          <div className="text">
+                            <Tooltip title={item.targetName}>{item.targetName}</Tooltip>
+                          </div>
+                        </div>
                       </div>
                       </div>
                       <div className="alarm-log-right">
                       <div className="alarm-log-right">
                         <div className="alarm-log-time">
                         <div className="alarm-log-time">
@@ -174,7 +181,10 @@ const TabComponent = observer((props: Props) => {
                             {moment(item.alarmDate).format('YYYY-MM-DD HH:mm:ss')}
                             {moment(item.alarmDate).format('YYYY-MM-DD HH:mm:ss')}
                           </div>
                           </div>
                         </div>
                         </div>
-                        <div className="alarm-log-time" style={{ paddingLeft: 10 }}>
+                        <div
+                          className="alarm-log-time alarm-log-status"
+                          style={{ paddingLeft: 10 }}
+                        >
                           <div className="log-title">状态</div>
                           <div className="log-title">状态</div>
                           <div className="context">
                           <div className="context">
                             <Badge status={item.state.value === 'warning' ? 'error' : 'default'} />
                             <Badge status={item.state.value === 'warning' ? 'error' : 'default'} />
@@ -192,20 +202,26 @@ const TabComponent = observer((props: Props) => {
                     <div className="alarm-log-actions">
                     <div className="alarm-log-actions">
                       <Space>
                       <Space>
                         {item.state.value === 'warning' && (
                         {item.state.value === 'warning' && (
-                          <div className="alarm-log-action">
-                            <Button
-                              type={'link'}
-                              onClick={() => {
-                                AlarmLogModel.solveVisible = true;
-                                AlarmLogModel.current = item;
-                              }}
-                            >
-                              <div className="btn">
-                                <ToolFilled className="icon" />
-                                <div>告警处理</div>
-                                {/* action */}
-                              </div>
-                            </Button>
+                          <div
+                            className={classNames(
+                              permission.action ? 'alarm-log-action' : 'alarm-log-disabled',
+                            )}
+                          >
+                            <Tooltip title={permission.action ? '' : '暂无权限,请联系管理员'}>
+                              <Button
+                                type={'link'}
+                                disabled={!permission.action}
+                                onClick={() => {
+                                  AlarmLogModel.solveVisible = true;
+                                  AlarmLogModel.current = item;
+                                }}
+                              >
+                                <div className="btn">
+                                  <ToolFilled className="icon" />
+                                  <div>告警处理</div>
+                                </div>
+                              </Button>
+                            </Tooltip>
                           </div>
                           </div>
                         )}
                         )}
                         <div className="alarm-log-action">
                         <div className="alarm-log-action">

+ 2 - 0
src/pages/rule-engine/Alarm/Log/index.tsx

@@ -4,6 +4,7 @@ import { useEffect } from 'react';
 import { AlarmLogModel } from './model';
 import { AlarmLogModel } from './model';
 import TabComponent from './TabComponent';
 import TabComponent from './TabComponent';
 import Service from './service';
 import Service from './service';
+import { Store } from 'jetlinks-store';
 
 
 export const service = new Service('alarm/record');
 export const service = new Service('alarm/record');
 
 
@@ -30,6 +31,7 @@ const Log = observer(() => {
   useEffect(() => {
   useEffect(() => {
     service.queryDefaultLevel().then((resp) => {
     service.queryDefaultLevel().then((resp) => {
       if (resp.status === 200) {
       if (resp.status === 200) {
+        Store.set('default-level', resp.result?.levels || []);
         AlarmLogModel.defaultLevel = resp.result?.levels || [];
         AlarmLogModel.defaultLevel = resp.result?.levels || [];
       }
       }
     });
     });

+ 6 - 1
src/pages/rule-engine/Alarm/Log/model.ts

@@ -21,18 +21,23 @@ export const AlarmLogModel = model<{
     {
     {
       dataIndex: 'alarmTime',
       dataIndex: 'alarmTime',
       title: '告警时间',
       title: '告警时间',
+      valueType: 'dateTime',
     },
     },
     {
     {
-      dataIndex: 'alarmName',
+      dataIndex: 'alarmConfigName',
       title: '告警名称',
       title: '告警名称',
+      hideInSearch: true,
     },
     },
     {
     {
       dataIndex: 'description',
       dataIndex: 'description',
       title: '说明',
       title: '说明',
+      hideInSearch: true,
     },
     },
     {
     {
       dataIndex: 'action',
       dataIndex: 'action',
       title: '操作',
       title: '操作',
+      hideInSearch: true,
+      valueType: 'option',
     },
     },
   ],
   ],
 });
 });

+ 56 - 114
src/pages/rule-engine/Scene/TriggerTerm/index.tsx

@@ -14,7 +14,13 @@ import {
   TreeSelect,
   TreeSelect,
 } from '@formily/antd';
 } from '@formily/antd';
 import { ISchema } from '@formily/json-schema';
 import { ISchema } from '@formily/json-schema';
-import { createForm, Field, onFieldReact, onFormValuesChange } from '@formily/core';
+import {
+  createForm,
+  Field,
+  onFieldReact,
+  onFieldValueChange,
+  onFormValuesChange,
+} from '@formily/core';
 import { forwardRef, useImperativeHandle, useMemo, useRef } from 'react';
 import { forwardRef, useImperativeHandle, useMemo, useRef } from 'react';
 import FTermArrayCards from '@/components/FTermArrayCards';
 import FTermArrayCards from '@/components/FTermArrayCards';
 import FTermTypeSelect from '@/components/FTermTypeSelect';
 import FTermTypeSelect from '@/components/FTermTypeSelect';
@@ -23,6 +29,7 @@ import Service from '@/pages/rule-engine/Scene/service';
 import { useAsyncDataSource } from '@/utils/util';
 import { useAsyncDataSource } from '@/utils/util';
 import { Store } from 'jetlinks-store';
 import { Store } from 'jetlinks-store';
 import { treeFilter } from '@/utils/tree';
 import { treeFilter } from '@/utils/tree';
+import FInputGroup from '@/components/FInputGroup';
 
 
 const service = new Service('scene');
 const service = new Service('scene');
 
 
@@ -34,56 +41,9 @@ interface Props {
 }
 }
 
 
 const TriggerTerm = (props: Props, ref: any) => {
 const TriggerTerm = (props: Props, ref: any) => {
-  const requestParams = {
-    trigger: {
-      type: 'device',
-      device: {
-        productId: '0412-zj',
-        selector: 'device',
-        selectorValue: [
-          {
-            id: '0412-zj',
-            name: '0412-zj',
-          },
-        ],
-        operation: {
-          operator: 'reportProperty',
-          timer: {
-            trigger: 'week',
-            cron: '',
-            when: [1, 3, 5],
-            mod: 'period',
-            period: {
-              from: '09:30',
-              to: '14:30',
-              every: 1,
-              unit: 'hours',
-            },
-            once: {
-              time: '',
-            },
-          },
-          eventId: '',
-          readProperties: ['temparature', 'temperature-k', 'test-zhibioa'],
-          writeProperties: {},
-          functionId: '',
-          functionParameters: [
-            {
-              name: '',
-              value: {},
-            },
-          ],
-        },
-        defaultVariable: [],
-      },
-      timer: {},
-      defaultVariable: [],
-    },
-  };
-
   const parseTermRef = useRef<any>();
   const parseTermRef = useRef<any>();
   const getParseTerm = () =>
   const getParseTerm = () =>
-    service.getParseTerm(requestParams || props.params).then((data) => {
+    service.getParseTerm(props.params).then((data) => {
       Store.set('trigger-parse-term', data);
       Store.set('trigger-parse-term', data);
       parseTermRef.current = data;
       parseTermRef.current = data;
       return data.map((item: any) => ({
       return data.map((item: any) => ({
@@ -97,55 +57,7 @@ const TriggerTerm = (props: Props, ref: any) => {
     () =>
     () =>
       createForm({
       createForm({
         validateFirst: true,
         validateFirst: true,
-        initialValues:
-          {
-            trigger: [
-              {
-                terms: [
-                  {
-                    column: 'properties.temprature.current',
-                    termType: 'gt',
-                    source: 'manual',
-                    value: 123,
-                  },
-                  {
-                    column: 'properties.test-zhibioa.recent',
-                    termType: 'gt',
-                    source: 'metrics',
-                    value: '123',
-                  },
-                  {
-                    column: 'properties.test-zhibioa.current',
-                    termType: 'lte',
-                    source: 'manual',
-                    value: 223,
-                  },
-                ],
-              },
-              {
-                terms: [
-                  {
-                    column: 'properties.temprature.current',
-                    termType: 'btw',
-                    source: 'manual',
-                    value: 23,
-                  },
-                  {
-                    column: 'properties.temperature-k.current',
-                    termType: 'gt',
-                    source: 'manual',
-                    value: 123,
-                  },
-                  {
-                    column: '_now',
-                    termType: 'eq',
-                    source: 'manual',
-                    value: '2022-04-29 00:00:07',
-                  },
-                ],
-              },
-            ],
-          } || props.value,
+        initialValues: props.value,
 
 
         effects() {
         effects() {
           onFormValuesChange(async (f) => {
           onFormValuesChange(async (f) => {
@@ -153,18 +65,25 @@ const TriggerTerm = (props: Props, ref: any) => {
               props.onChange(await f.submit());
               props.onChange(await f.submit());
             }
             }
           });
           });
+          onFieldValueChange('trigger.*.terms.*.column', (field, form1) => {
+            if (field.modified) {
+              form1.setFieldState(field.query('.value'), (state) => {
+                state.value = undefined;
+              });
+            }
+          });
           onFieldReact('trigger.*.terms.*.column', async (field, form1) => {
           onFieldReact('trigger.*.terms.*.column', async (field, form1) => {
             const operator = field.query('.termType');
             const operator = field.query('.termType');
             const value = (field as Field).value;
             const value = (field as Field).value;
 
 
             // 找到选中的
             // 找到选中的
-            const _data = await service.getParseTerm(requestParams || props.params);
+            const _data = await service.getParseTerm(props.params);
             if (!_data) return;
             if (!_data) return;
             // 树形搜索
             // 树形搜索
             const treeValue = treeFilter(_data, value, 'column');
             const treeValue = treeFilter(_data, value, 'column');
             // 找到
             // 找到
             const target =
             const target =
-              treeValue && treeValue[0].children
+              treeValue && treeValue[0]?.children
                 ? treeValue[0]?.children.find((item) => item.column === value)
                 ? treeValue[0]?.children.find((item) => item.column === value)
                 : treeValue[0];
                 : treeValue[0];
 
 
@@ -236,7 +155,7 @@ const TriggerTerm = (props: Props, ref: any) => {
           });
           });
         },
         },
       }),
       }),
-    [props.value],
+    [props.value, props.params],
   );
   );
 
 
   useImperativeHandle(ref, () => ({
   useImperativeHandle(ref, () => ({
@@ -254,6 +173,7 @@ const TriggerTerm = (props: Props, ref: any) => {
       FormGrid,
       FormGrid,
       FTermTypeSelect,
       FTermTypeSelect,
       TreeSelect,
       TreeSelect,
+      FInputGroup,
     },
     },
   });
   });
 
 
@@ -302,7 +222,7 @@ const TriggerTerm = (props: Props, ref: any) => {
                         'x-decorator': 'FormItem',
                         'x-decorator': 'FormItem',
                         'x-component': 'TreeSelect',
                         'x-component': 'TreeSelect',
                         'x-decorator-props': {
                         'x-decorator-props': {
-                          gridSpan: 4,
+                          gridSpan: 6,
                         },
                         },
                         'x-component-props': {
                         'x-component-props': {
                           placeholder: '请选择参数',
                           placeholder: '请选择参数',
@@ -322,21 +242,43 @@ const TriggerTerm = (props: Props, ref: any) => {
                           placeholder: '操作符',
                           placeholder: '操作符',
                         },
                         },
                       },
                       },
-                      source: {
-                        type: 'string',
+                      inputGroup: {
+                        type: 'void',
+                        'x-component': 'FInputGroup',
                         'x-decorator': 'FormItem',
                         'x-decorator': 'FormItem',
-                        'x-component': 'Select',
                         'x-decorator-props': {
                         'x-decorator-props': {
-                          gridSpan: 1,
+                          gridSpan: 4,
+                          style: {
+                            width: '100%',
+                          },
                         },
                         },
-                      },
-                      value: {
-                        type: 'string',
-                        'x-decorator': 'FormItem',
-                        'x-component': 'Input',
-                        'x-component-props': {},
-                        'x-decorator-props': {
-                          gridSpan: 3,
+                        'x-component-props': {
+                          compact: true,
+                          style: {
+                            width: '100%',
+                          },
+                        },
+                        properties: {
+                          source: {
+                            type: 'string',
+                            'x-component': 'Select',
+                            'x-decorator': 'FormItem',
+                            'x-component-props': {
+                              style: {
+                                minWidth: '110px',
+                              },
+                            },
+                          },
+                          value: {
+                            type: 'string',
+                            'x-component': 'Input',
+                            'x-decorator': 'FormItem',
+                            'x-decorator-props': {
+                              style: {
+                                width: 'calc(100% - 110px)',
+                              },
+                            },
+                          },
                         },
                         },
                       },
                       },
                       remove: {
                       remove: {

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

@@ -129,6 +129,7 @@ export enum BUTTON_PERMISSION_ENUM {
   'channel' = 'channel',
   'channel' = 'channel',
   'debug' = 'debug',
   'debug' = 'debug',
   'log' = 'log',
   'log' = 'log',
+  'tigger' = 'tigger',
 }
 }
 
 
 // 调试按钮、通知记录、批量导出、批量导入、选择通道、推送、分配资产、绑定用户对应的ID是啥
 // 调试按钮、通知记录、批量导出、批量导入、选择通道、推送、分配资产、绑定用户对应的ID是啥

+ 1 - 1
src/utils/util.ts

@@ -37,7 +37,7 @@ export const downloadFile = (url: string, params?: Record<string, any>) => {
  * @param record
  * @param record
  * @param fileName
  * @param fileName
  */
  */
-export const downloadObject = (record: Record<string, unknown>, fileName: string) => {
+export const downloadObject = (record: Record<string, any>, fileName: string) => {
   // 创建隐藏的可下载链接
   // 创建隐藏的可下载链接
   const ghostLink = document.createElement('a');
   const ghostLink = document.createElement('a');
   ghostLink.download = `${fileName}-${
   ghostLink.download = `${fileName}-${