wzyyy 3 anos atrás
pai
commit
e36a0cb392

+ 0 - 1
src/components/ProTableCard/CardItems/DataCollect/channel.tsx

@@ -26,7 +26,6 @@ export default (props: ChannelCardProps) => {
     <TableCard
       actions={props.actions}
       status={props.state?.value}
-      showStatus={false}
       statusText={props.state?.text}
       showMask={false}
       statusNames={{

+ 16 - 7
src/components/ProTableCard/CardItems/Scene/index.less

@@ -22,11 +22,20 @@
   }
   .card-item-content-box {
     .card-item-content-trigger {
-      color: rgba(0, 0, 0, 0.85);
-      font-weight: bold;
-      font-size: 15px;
+      display: flex;
+      .card-item-content-trigger-item {
+        width: max-content;
+        color: rgba(0, 0, 0, 0.85);
+        font-weight: bold;
+        font-size: 15px;
+        &:not(:last-child) {
+          margin-right: 10px;
+        }
+      }
       .trigger-device {
         color: rgba(47, 84, 235);
+        font-weight: bold;
+        font-size: 15px;
       }
     }
     .card-item-content-action-item {
@@ -48,7 +57,6 @@
           width: 100%;
           .trigger-contents {
             color: rgba(0, 0, 0, 0.85);
-            //width: calc(85% - 110px);
           }
           .right-item-left {
             width: 15%;
@@ -61,13 +69,11 @@
           }
           .right-item-right {
             width: 85%;
-            padding-left: 20px;
             .right-item-right-item {
               display: flex;
               width: 100%;
               .trigger-ways {
-                width: 75px;
-                margin-right: 20px;
+                width: 70px;
                 color: rgba(0, 0, 0, 0.85);
                 font-size: 16px;
               }
@@ -82,6 +88,9 @@
                 }
               }
             }
+            &:not(:first-child) {
+              padding-left: 20px;
+            }
           }
         }
       }

+ 63 - 19
src/components/ProTableCard/CardItems/Scene/index.tsx

@@ -318,25 +318,65 @@ const ContentRender = (data: SceneCardProps) => {
   const type = data.triggerType;
   if (!!type && (data.branches || [])?.length) {
     const trigger = data?.options?.trigger;
-    const text =
-      (trigger?.name || '') +
-      (trigger?.productName || '') +
-      (trigger?.when || '') +
-      (trigger?.time || '') +
-      (trigger?.extraTime || '') +
-      (trigger?.type || '');
     return (
       <div className={styles['card-item-content-box']}>
-        <MyTooltip placement="topLeft" title={text}>
-          <div className={classNames(styles['card-item-content-trigger'], 'ellipsis')}>
-            {trigger?.name || ''}
-            <span className={styles['trigger-device']}>{trigger?.productName || ''}</span>
-            {(trigger?.when || '') +
-              (trigger?.time || '') +
-              (trigger?.extraTime || '') +
-              (trigger?.type || '')}
-          </div>
-        </MyTooltip>
+        <div className={classNames(styles['card-item-content-trigger'])}>
+          {trigger?.name && (
+            <MyTooltip placement="topLeft" title={trigger?.name || ''}>
+              <div
+                className={classNames(styles['card-item-content-trigger-item'], 'ellipsis')}
+                style={{ maxWidth: '15%', color: 'rgba(47, 84, 235)' }}
+              >
+                {trigger?.name || ''}
+              </div>
+            </MyTooltip>
+          )}
+          {trigger?.productName && (
+            <MyTooltip placement="topLeft" title={trigger?.productName || ''}>
+              <div
+                className={classNames(styles['card-item-content-trigger-item'], 'ellipsis')}
+                style={{ maxWidth: '15%', color: 'rgba(47, 84, 235)' }}
+              >
+                {trigger?.productName || ''}
+              </div>
+            </MyTooltip>
+          )}
+          {trigger?.when && (
+            <MyTooltip placement="topLeft" title={trigger?.when || ''}>
+              <div
+                className={classNames(styles['card-item-content-trigger-item'], 'ellipsis')}
+                style={{ maxWidth: '15%' }}
+              >
+                {trigger?.when || ''}
+              </div>
+            </MyTooltip>
+          )}
+          {trigger?.time && (
+            <div className={classNames(styles['card-item-content-trigger-item'])}>
+              {trigger?.time || ''}
+            </div>
+          )}
+          {trigger?.extraTime && (
+            <div className={classNames(styles['card-item-content-trigger-item'])}>
+              {trigger?.extraTime || ''}
+            </div>
+          )}
+          {trigger?.action && (
+            <MyTooltip placement="topLeft" title={trigger?.action || ''}>
+              <div
+                className={classNames(styles['card-item-content-trigger-item'], 'ellipsis')}
+                style={{ maxWidth: '15%' }}
+              >
+                {trigger?.action || ''}
+              </div>
+            </MyTooltip>
+          )}
+          {trigger?.type && (
+            <div className={classNames(styles['card-item-content-trigger-item'])}>
+              {trigger?.type || ''}
+            </div>
+          )}
+        </div>
         <div className={styles['card-item-content-action']}>
           {(visible ? data.branches || [] : (data?.branches || []).slice(0, 2)).map(
             (item: any, index) => {
@@ -350,7 +390,9 @@ const ContentRender = (data: SceneCardProps) => {
                       {type === 'device' && (
                         <div
                           className={styles['right-item-left']}
-                          style={{ width: item?.then && item?.then.length ? '15%' : '100%' }}
+                          style={{
+                            width: Array.isArray(item.then) && item?.then.length ? '15%' : '100%',
+                          }}
                         >
                           <MyTooltip
                             placement={'topLeft'}
@@ -373,7 +415,7 @@ const ContentRender = (data: SceneCardProps) => {
                           )}
                         </div>
                       )}
-                      {item?.then && item?.then.length && (
+                      {Array.isArray(item.then) && item?.then.length ? (
                         <div
                           className={styles['right-item-right']}
                           style={{ width: type === 'device' ? '85%' : '100%' }}
@@ -389,6 +431,8 @@ const ContentRender = (data: SceneCardProps) => {
                             </div>
                           ))}
                         </div>
+                      ) : (
+                        ''
                       )}
                     </div>
                   </div>

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

@@ -44,7 +44,7 @@ export default (props: ResourceCardProps) => {
             </div>
             <div>
               <label>所属边缘网关</label>
-              <Ellipsis title={props?.category || ''} />
+              <Ellipsis title={props?.sourceName || ''} />
             </div>
           </div>
         </div>

+ 5 - 4
src/pages/edge/Resource/index.tsx

@@ -28,11 +28,12 @@ export default () => {
   const [current, setCurrent] = useState<Partial<ResourceItem>>({});
   const [visible, setVisible] = useState<boolean>(false);
   const [issueVisible, setIssueVisible] = useState<boolean>(false);
+  const { permission } = PermissionButton.usePermission('edge/Resource');
 
   const tools = (record: ResourceItem, type: 'card' | 'list') => [
     <PermissionButton
       type={'link'}
-      isPermission={true}
+      isPermission={permission.update}
       onClick={() => {
         setCurrent(record);
         setVisible(true);
@@ -56,7 +57,7 @@ export default () => {
         title: type !== 'list' ? '' : '下发',
       }}
       style={{ padding: 0 }}
-      isPermission={true}
+      isPermission={permission.setting}
       key={'reset'}
     >
       <DownSquareOutlined />
@@ -99,7 +100,7 @@ export default () => {
           }
         },
       }}
-      isPermission={true}
+      isPermission={permission.action}
       tooltip={{
         title: type === 'list' ? (record.state.value !== 'disabled' ? '禁用' : '启用') : '',
       }}
@@ -117,7 +118,7 @@ export default () => {
       type={'link'}
       key={'delete'}
       style={{ padding: 0 }}
-      isPermission={true}
+      isPermission={permission.delete}
       tooltip={record.state.value !== 'notActive' ? { title: '请先禁用,再删除。' } : undefined}
       disabled={record.state.value !== 'notActive'}
       popConfirm={{

+ 1 - 0
src/pages/edge/Resource/typings.d.ts

@@ -5,6 +5,7 @@ type ResourceItem = {
   targetType: string;
   sourceId: string;
   sourceType: string;
+  sourceName: string;
   metadata: string;
   state: {
     value: string;

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

@@ -676,7 +676,7 @@ export default () => {
   return (
     <PageContainer>
       <div className={'link-dash-board'}>
-        {serverNode && serverNode.length ? (
+        {serverNode && serverNode.length > 1 ? (
           <div style={{ backgroundColor: '#fff', padding: '24px 24px 0 24px' }}>
             <Select
               value={serverId}
@@ -691,7 +691,7 @@ export default () => {
         <div className={'echarts-items'}>
           <TopEchartsItemNode title={'CPU使用率'} value={topValues.cpu} />
           <TopEchartsItemNode
-            title={'JVM内存'}
+            title={'JVM内存占用'}
             formatter={'G'}
             value={topValues.jvm}
             max={topValues.jvmTotal}
@@ -705,11 +705,11 @@ export default () => {
             bottom={`总磁盘大小  ${topValues.usageTotal}G`}
           />
           <TopEchartsItemNode
-            title={'系统内存'}
+            title={'系统内存占用'}
             formatter={'G'}
             value={topValues.systemUsage}
             max={topValues.systemUsageTotal}
-            bottom={`系统内存  ${topValues.systemUsageTotal}G`}
+            bottom={`系统内存  ${topValues.systemUsageTotal}G`}
           />
         </div>
         <div style={{ marginBottom: 24 }}>

+ 1 - 1
src/pages/link/DataCollect/DataGathering/index.tsx

@@ -8,7 +8,7 @@ import Device from '../components/Device';
 import Point from '../components/Point';
 import { Empty } from '@/components';
 
-const DataCollectModel = model<{
+export const DataCollectModel = model<{
   id: Partial<string>;
   type: 'channel' | 'device' | undefined;
   provider: 'OPC_UA' | 'MODBUS_TCP';

+ 57 - 15
src/pages/link/DataCollect/components/Channel/index.tsx

@@ -6,7 +6,7 @@ import { useDomFullHeight } from '@/hooks';
 import service from '@/pages/link/DataCollect/service';
 import ChannelCard from '@/components/ProTableCard/CardItems/DataCollect/channel';
 import { Empty, PermissionButton } from '@/components';
-import { DeleteOutlined, EditOutlined } from '@ant-design/icons';
+import { DeleteOutlined, EditOutlined, PlayCircleOutlined, StopOutlined } from '@ant-design/icons';
 import { onlyMessage } from '@/utils/util';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { Card, Col, Pagination, Row } from 'antd';
@@ -62,7 +62,6 @@ export default observer((props: Props) => {
       title: '状态',
       dataIndex: 'state',
       valueType: 'select',
-      hideInSearch: true,
       valueEnum: {
         enabled: {
           text: '正常',
@@ -78,7 +77,6 @@ export default observer((props: Props) => {
       title: '运行状态',
       dataIndex: 'runningState',
       valueType: 'select',
-      hideInSearch: true,
       valueEnum: {
         running: {
           text: '运行中',
@@ -92,10 +90,10 @@ export default observer((props: Props) => {
           text: '错误',
           status: 'failed',
         },
-        stopped: {
-          text: '已停止',
-          status: 'stopped',
-        },
+        // stopped: {
+        //   text: '已停止',
+        //   status: 'stopped',
+        // },
       },
     },
     {
@@ -179,18 +177,62 @@ export default observer((props: Props) => {
                         })}
                       </PermissionButton>,
                       <PermissionButton
+                        key={'action'}
+                        type={'link'}
+                        style={{ padding: 0 }}
+                        isPermission={permission.action}
+                        popConfirm={{
+                          title: intl.formatMessage({
+                            id: `pages.data.option.${
+                              record?.state?.value !== 'disabled' ? 'disabled' : 'enabled'
+                            }.tips`,
+                            defaultMessage: '确认禁用?',
+                          }),
+                          onConfirm: async () => {
+                            const resp =
+                              record?.state?.value !== 'disabled'
+                                ? await service.updateChannel(record.id, {
+                                    state: 'disabled',
+                                    runningState: 'stopped',
+                                  })
+                                : await service.updateChannel(record.id, {
+                                    state: 'enabled',
+                                    runningState: 'running',
+                                  });
+                            if (resp.status === 200) {
+                              onlyMessage('操作成功!');
+                              handleSearch(param);
+                            } else {
+                              onlyMessage('操作失败!', 'error');
+                            }
+                          },
+                        }}
+                      >
+                        {record?.state?.value !== 'disabled' ? (
+                          <StopOutlined />
+                        ) : (
+                          <PlayCircleOutlined />
+                        )}
+                        {intl.formatMessage({
+                          id: `pages.data.option.${
+                            record?.state?.value !== 'disabled' ? 'disabled' : 'enabled'
+                          }`,
+                          defaultMessage: record?.state?.value !== 'disabled' ? '禁用' : '启用',
+                        })}
+                      </PermissionButton>,
+                      <PermissionButton
                         key="delete"
                         isPermission={permission.delete}
                         type={'link'}
                         style={{ padding: 0 }}
-                        // disabled={record?.state?.value !== 'disabled'}
-                        // tooltip={
-                        //   record?.state?.value !== 'disabled'
-                        //     ? {
-                        //         title: '正常的通道不能删除',
-                        //       }
-                        //     : undefined
-                        // }
+                        disabled={record?.state?.value !== 'disabled'}
+                        tooltip={
+                          record?.state?.value !== 'disabled'
+                            ? {
+                                title: '正常的通道不能删除',
+                              }
+                            : undefined
+                        }
                         popConfirm={{
                           title: '该操作将会删除下属采集器与点位,确定删除?',
                           placement: 'topRight',

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

@@ -172,6 +172,7 @@ export default (props: Props) => {
             'x-decorator': 'FormItem',
             'x-decorator-props': {
               gridSpan: 2,
+              tooltip: '统一配置所有点位的大小端',
             },
             'x-component-props': {
               placeholder: '请选择大小端',

+ 11 - 9
src/pages/link/DataCollect/components/Device/index.tsx

@@ -101,10 +101,10 @@ export default observer((props: Props) => {
               text: '错误',
               status: 'failed',
             },
-            stopped: {
-              text: '已停止',
-              status: 'stopped',
-            },
+            // stopped: {
+            //   text: '已停止',
+            //   status: 'stopped',
+            // },
           },
         },
         {
@@ -149,10 +149,10 @@ export default observer((props: Props) => {
               text: '错误',
               status: 'failed',
             },
-            stopped: {
-              text: '已停止',
-              status: 'stopped',
-            },
+            // stopped: {
+            //   text: '已停止',
+            //   status: 'stopped',
+            // },
           },
         },
         {
@@ -279,9 +279,11 @@ export default observer((props: Props) => {
                                   record?.state?.value !== 'disabled'
                                     ? await service.updateCollector(record.id, {
                                         state: 'disabled',
+                                        runningState: 'stopped',
                                       })
                                     : await service.updateCollector(record.id, {
                                         state: 'enabled',
+                                        runningState: 'running',
                                       });
                                 if (resp.status === 200) {
                                   onlyMessage('操作成功!');
@@ -315,7 +317,7 @@ export default observer((props: Props) => {
                             tooltip={
                               record?.state?.value !== 'disabled'
                                 ? {
-                                    title: '已启用的采集器不能删除',
+                                    title: '正常的采集器不能删除',
                                   }
                                 : undefined
                             }

+ 70 - 26
src/pages/link/DataCollect/components/Tree/index.tsx

@@ -18,6 +18,7 @@ import CollectorSave from '../../components/Device/Save/index';
 import { onlyMessage } from '@/utils/util';
 // import { StatusColorEnum } from '@/components/BadgeStatus';
 import { useIntl } from '@@/plugin-locale/localeExports';
+import { DataCollectModel } from '../../DataGathering';
 
 const TreeModel = model<{
   selectedKeys: string[];
@@ -55,7 +56,7 @@ export default observer((props: Props) => {
   const { permission } = PermissionButton.usePermission('link/DataCollect/DataGathering');
   const intl = useIntl();
 
-  const handleSearch = (params: any) => {
+  const handleSearch = (params: any, reload?: boolean) => {
     TreeModel.loading = true;
     TreeModel.param = params;
     service
@@ -64,8 +65,11 @@ export default observer((props: Props) => {
         if (resp.status === 200) {
           TreeModel.dataSource = resp.result;
           if (resp.result.length) {
-            TreeModel.selectedKeys = [resp.result[0].id];
-            props.change(resp.result[0].id, 'channel', resp.result[0].provider);
+            if (!reload) {
+              TreeModel.selectedKeys = [resp.result[0].id];
+            }
+            const provider = !reload ? resp.result[0].provider : DataCollectModel.provider;
+            props.change(TreeModel.selectedKeys[0], 'channel', provider);
           }
         }
         TreeModel.loading = false;
@@ -73,28 +77,12 @@ export default observer((props: Props) => {
   };
 
   useEffect(() => {
-    handleSearch(TreeModel.param);
-  }, [TreeModel.param, props.reload]);
+    handleSearch(TreeModel.param, false);
+  }, [TreeModel.param]);
 
-  // const getState = (record: Partial<ChannelItem>): { text: string; value: string } => {
-  //   if (record) {
-  //     if (record?.state?.value === 'enabled') {
-  //       return {
-  //         text: record?.runningState?.text || '',
-  //         value: record?.runningState?.value || '',
-  //       };
-  //     } else {
-  //       return {
-  //         text: '禁用',
-  //         value: 'disabled',
-  //       };
-  //     }
-  //   }
-  //   return {
-  //     text: '',
-  //     value: '',
-  //   };
-  // };
+  useEffect(() => {
+    handleSearch(TreeModel.param, true);
+  }, [props.reload]);
 
   const getState = (record: any) => {
     if (record) {
@@ -187,7 +175,44 @@ export default observer((props: Props) => {
                             />
                           </Tooltip>
                           <Popconfirm
+                            title={intl.formatMessage({
+                              id: `pages.data.option.${
+                                item?.state?.value !== 'disabled' ? 'disabled' : 'enabled'
+                              }.tips`,
+                              defaultMessage: '确认禁用?',
+                            })}
+                            onConfirm={async () => {
+                              const resp =
+                                item?.state?.value !== 'disabled'
+                                  ? await service.updateChannel(item.id, {
+                                      state: 'disabled',
+                                      runningState: 'stopped',
+                                    })
+                                  : await service.updateChannel(item.id, {
+                                      state: 'enabled',
+                                      runningState: 'running',
+                                    });
+                              if (resp.status === 200) {
+                                TreeModel.param = {};
+                                handleSearch(TreeModel.param);
+                                props.onReload();
+                                onlyMessage('操作成功');
+                              } else {
+                                onlyMessage('操作失败!', 'error');
+                              }
+                            }}
+                          >
+                            <Tooltip title={!permission.action ? '暂无权限,请联系管理员' : ''}>
+                              {item?.state?.value !== 'disabled' ? (
+                                <StopOutlined />
+                              ) : (
+                                <PlayCircleOutlined />
+                              )}
+                            </Tooltip>
+                          </Popconfirm>
+                          <Popconfirm
                             title={'该操作将会删除下属采集器与点位,确定删除?'}
+                            disabled={item?.state?.value !== 'disabled'}
                             onConfirm={async () => {
                               const resp = await service.removeChannel(item.id);
                               if (resp.status === 200) {
@@ -197,7 +222,15 @@ export default observer((props: Props) => {
                               }
                             }}
                           >
-                            <Tooltip title={!permission.delete ? '暂无权限,请联系管理员' : ''}>
+                            <Tooltip
+                              title={
+                                !permission.delete
+                                  ? '暂无权限,请联系管理员'
+                                  : item?.state?.value !== 'disabled'
+                                  ? '正常的通道不能删除'
+                                  : ''
+                              }
+                            >
                               <DeleteOutlined />
                             </Tooltip>
                           </Popconfirm>
@@ -260,9 +293,11 @@ export default observer((props: Props) => {
                                     i?.state?.value !== 'disabled'
                                       ? await service.updateCollector(i.id, {
                                           state: 'disabled',
+                                          runningState: 'stopped',
                                         })
                                       : await service.updateCollector(i.id, {
                                           state: 'enabled',
+                                          runningState: 'running',
                                         });
                                   if (resp.status === 200) {
                                     TreeModel.param = {};
@@ -284,6 +319,7 @@ export default observer((props: Props) => {
                               </Popconfirm>
                               <Popconfirm
                                 title={'该操作将会删除下属点位,确定删除?'}
+                                disabled={i?.state?.value !== 'disabled'}
                                 onConfirm={async () => {
                                   const resp = await service.removeCollector(i.id);
                                   if (resp.status === 200) {
@@ -293,7 +329,15 @@ export default observer((props: Props) => {
                                   }
                                 }}
                               >
-                                <Tooltip title={!permission.delete ? '暂无权限,请联系管理员' : ''}>
+                                <Tooltip
+                                  title={
+                                    !permission.delete
+                                      ? '暂无权限,请联系管理员'
+                                      : i?.state?.value !== 'disabled'
+                                      ? '正常的采集器不能删除'
+                                      : ''
+                                  }
+                                >
                                   <DeleteOutlined />
                                 </Tooltip>
                               </Popconfirm>

+ 26 - 13
src/pages/rule-engine/Scene/Save/action/ListItem/Item.tsx

@@ -1,5 +1,5 @@
 import { useEffect, useState, useRef } from 'react';
-import Modal from '../Modal/add';
+import Modal, { ActionTypeComponent } from '../Modal/add';
 import type { ActionsType } from '@/pages/rule-engine/Scene/typings';
 import { DeleteOutlined } from '@ant-design/icons';
 import './index.less';
@@ -45,6 +45,7 @@ export default (props: ItemProps) => {
   const [triggerVisible, setTriggerVisible] = useState<boolean>(false);
   const [op, setOp] = useState<any>(props.options);
   const cacheValueRef = useRef<any>({});
+  const [actionType, setActionType] = useState<string>('');
 
   useEffect(() => {
     setOp(props.options);
@@ -189,7 +190,6 @@ export default (props: ItemProps) => {
   };
 
   const contentRender = () => {
-    // console.log('props.data', props.data)
     if (props?.data?.alarm?.mode === 'trigger') {
       return (
         <div className={'item-options-content'}>
@@ -206,12 +206,7 @@ export default (props: ItemProps) => {
       );
     } else if (props?.data?.alarm?.mode === 'relieve') {
       return (
-        <div
-          className={'item-options-content'}
-          onClick={() => {
-            setVisible(true);
-          }}
-        >
+        <div className={'item-options-content'}>
           满足条件后将解除关联
           <a
             onClick={() => {
@@ -227,7 +222,7 @@ export default (props: ItemProps) => {
         <div
           className={'item-options-content'}
           onClick={() => {
-            setVisible(true);
+            setActionType(props?.data?.executor);
           }}
         >
           {notifyRender(props?.data, props?.options)}
@@ -238,7 +233,7 @@ export default (props: ItemProps) => {
         <div
           className={'item-options-content'}
           onClick={() => {
-            setVisible(true);
+            setActionType(props?.data?.executor);
           }}
         >
           {props.options.name}
@@ -249,7 +244,7 @@ export default (props: ItemProps) => {
         <div
           className={'item-options-content'}
           onClick={() => {
-            setVisible(true);
+            setActionType(props?.data?.executor);
           }}
         >
           {deviceRender(props?.data)}
@@ -275,7 +270,12 @@ export default (props: ItemProps) => {
     <div className="actions-item-warp">
       <div className="actions-item">
         <div className="item-options-warp">
-          <div className="item-options-type">
+          <div
+            className="item-options-type"
+            onClick={() => {
+              setVisible(true);
+            }}
+          >
             <img
               style={{ width: 18 }}
               src={iconMap.get(
@@ -340,7 +340,6 @@ export default (props: ItemProps) => {
             setVisible(false);
           }}
           save={(data: ActionsType, options) => {
-            // FormModel.actions[props.name] = data;
             setOp(options);
             props.onUpdate(data, options);
             setVisible(false);
@@ -355,6 +354,20 @@ export default (props: ItemProps) => {
           }}
         />
       )}
+      <ActionTypeComponent
+        name={props.name}
+        data={props.data}
+        type={actionType}
+        close={() => {
+          setActionType('');
+        }}
+        save={(data: ActionsType, options) => {
+          setOp(options);
+          props.onUpdate(data, options);
+          setActionType('');
+        }}
+        parallel={props.parallel}
+      />
     </div>
   );
 };

+ 97 - 81
src/pages/rule-engine/Scene/Save/action/Modal/add.tsx

@@ -6,6 +6,90 @@ import type { ActionsType } from '@/pages/rule-engine/Scene/typings';
 import Device from '../DeviceOutput';
 import Delay from '../Delay';
 
+interface ActionTypeProps {
+  type: string;
+  name: number;
+  save: (data: any, options?: any) => void;
+  data: Partial<ActionsType>;
+  close: () => void;
+  parallel: boolean;
+}
+
+export const ActionTypeComponent = (props: ActionTypeProps) => {
+  const { type } = props;
+  switch (type) {
+    case 'device':
+      return (
+        <Device
+          value={props.data?.device}
+          save={(data: any, options: any) => {
+            props.save(
+              {
+                type: 'device',
+                executor: 'device',
+                key: props.data.key || `device_${new Date().getTime()}`,
+                device: {
+                  ...data,
+                },
+              },
+              options,
+            );
+          }}
+          name={props.name}
+          cancel={() => {
+            props.close();
+          }}
+          parallel={props.parallel}
+        />
+      );
+    case 'notify':
+      return (
+        <Notify
+          value={props.data?.notify || {}}
+          options={props.data?.options || {}}
+          save={(data: any, option: any) => {
+            props.save(
+              {
+                ...data,
+                executor: 'notify',
+                key: props.data.key || `notify_${new Date().getTime()}`,
+              },
+              option,
+            );
+          }}
+          name={props.name}
+          cancel={() => {
+            props.close();
+          }}
+        />
+      );
+    case 'delay':
+      return (
+        <Delay
+          value={props.data?.delay || {}}
+          save={(data: any, options) => {
+            props.save(
+              {
+                type: 'delay',
+                executor: 'delay',
+                key: props.data.key || `delay_${new Date().getTime()}`,
+                delay: {
+                  ...data,
+                },
+              },
+              options,
+            );
+          }}
+          cancel={() => {
+            props.close();
+          }}
+        />
+      );
+    default:
+      return null;
+  }
+};
+
 interface Props {
   close: () => void;
   save: (data: any, options?: any) => void;
@@ -22,88 +106,11 @@ export default (props: Props) => {
   useEffect(() => {
     if (props.data?.executor) {
       form.setFieldsValue({
-        type: props.data.executor,
+        type: props.data.executor === 'alarm' ? props.data.alarm?.mode : props.data.executor,
       });
     }
   }, [props.data]);
 
-  const actionTypeComponent = (type: string) => {
-    switch (type) {
-      case 'device':
-        return (
-          <Device
-            value={props.data?.device}
-            save={(data: any, options: any) => {
-              setActionType('');
-              props.save(
-                {
-                  type: 'device',
-                  executor: 'device',
-                  key: props.data.key || `device_${new Date().getTime()}`,
-                  device: {
-                    ...data,
-                  },
-                },
-                options,
-              );
-            }}
-            name={props.name}
-            cancel={() => {
-              setActionType('');
-            }}
-            parallel={props.parallel}
-          />
-        );
-      case 'notify':
-        return (
-          <Notify
-            value={props.data?.notify || {}}
-            options={props.data?.options || {}}
-            save={(data: any, option: any) => {
-              setActionType('');
-              props.save(
-                {
-                  ...data,
-                  executor: 'notify',
-                  key: props.data.key || `notify_${new Date().getTime()}`,
-                },
-                option,
-              );
-            }}
-            name={props.name}
-            cancel={() => {
-              setActionType('');
-            }}
-          />
-        );
-      case 'delay':
-        return (
-          <Delay
-            value={props.data?.delay || {}}
-            save={(data: any, options) => {
-              setActionType('');
-              props.save(
-                {
-                  type: 'delay',
-                  executor: 'delay',
-                  key: props.data.key || `delay_${new Date().getTime()}`,
-                  delay: {
-                    ...data,
-                  },
-                },
-                options,
-              );
-            }}
-            cancel={() => {
-              setActionType('');
-            }}
-          />
-        );
-      default:
-        return null;
-    }
-  };
-
   return (
     <Modal
       title="类型"
@@ -116,8 +123,7 @@ export default (props: Props) => {
         const values = await form.validateFields();
         setActionType(values.type);
         if (values.type === 'relieve' || values.type === 'trigger') {
-          console.log(values.type, props.data);
-          props.save({ ...props.data, type: values.type, executor: values.type });
+          props.save({ ...props.data, type: values.type, executor: 'alarm' });
         }
       }}
     >
@@ -131,7 +137,17 @@ export default (props: Props) => {
           <ActionsTypeComponent parallel={props.parallel} />
         </Form.Item>
       </Form>
-      {actionTypeComponent(actionType)}
+      <ActionTypeComponent
+        {...props}
+        type={actionType}
+        save={(data: any, options?: any) => {
+          props.save(data, options);
+          setActionType('');
+        }}
+        close={() => {
+          setActionType('');
+        }}
+      />
     </Modal>
   );
 };

+ 1 - 1
src/pages/rule-engine/Scene/Save/action/notify/NotifyWay.tsx

@@ -53,7 +53,7 @@ export default forwardRef((props: NotifyWayProps, ref) => {
           name="notifyType"
           label="应用"
           required
-          rules={[{ required: true, message: '请选择类型' }]}
+          rules={[{ required: true, message: '请选择通知方式' }]}
         >
           <NotifyType options={list} />
         </Form.Item>

+ 9 - 1
src/pages/rule-engine/Scene/Save/action/notify/VariableDefinitions.tsx

@@ -21,7 +21,7 @@ export default forwardRef((props: Props, ref) => {
     switch (type) {
       case 'user':
         return <User />;
-      case 'org':
+      case '      ':
         return <Org />;
       case 'tag':
         return <Tag />;
@@ -191,6 +191,14 @@ export default forwardRef((props: Props, ref) => {
                     source: 'fixed',
                     value: undefined,
                   };
+          } else if (!['org', 'tag', 'file', 'link'].includes(type)) {
+            initialValue =
+              props?.value && item?.id && props?.value[item.id]
+                ? props?.value[item.id]
+                : {
+                    source: 'fixed',
+                    value: undefined,
+                  };
           } else {
             initialValue =
               props?.value && item?.id && props?.value[item.id] ? props?.value[item.id] : undefined;

+ 2 - 2
src/pages/rule-engine/Scene/Save/action/notify/components/variableItem/buildIn.tsx

@@ -20,7 +20,7 @@ interface BuiltInProps {
 }
 
 export default (props: BuiltInProps) => {
-  const [source, setSource] = useState(props.value?.source);
+  const [source, setSource] = useState(props.value?.source || 'fixed');
   const [value, setValue] = useState(props.value?.value);
   const [upperKey, setUpperKey] = useState(props.value?.upperKey);
 
@@ -58,7 +58,7 @@ export default (props: BuiltInProps) => {
   }, [source]);
 
   useEffect(() => {
-    setSource(props.value?.source);
+    setSource(props.value?.source || 'fixed');
     setValue(props.value?.value);
     setUpperKey(props.value?.upperKey);
   }, [props.value]);

+ 54 - 2
src/pages/system/Menu/Setting/baseMenu.ts

@@ -2334,8 +2334,8 @@ export default [
             owner: 'iot',
             sortIndex: 1,
             url: '/iot/edge/Devic',
-            icon: 'icon-changjingliandong',
-            showPage: ['device-instance'],
+            icon: 'icon-bumenguanli',
+            showPage: ['edge-operations'],
             permissions: [],
             buttons: [
               {
@@ -2420,6 +2420,58 @@ export default [
               },
             ],
           },
+          {
+            code: 'edge/Resource',
+            name: '资源库',
+            owner: 'iot',
+            sortIndex: 2,
+            url: '/iot/edge/Resource',
+            icon: 'icon-Vector',
+            showPage: ['edge-operations'],
+            permissions: [],
+            buttons: [
+              {
+                id: 'action',
+                name: '启/禁用',
+                permissions: [
+                  {
+                    permission: 'device-instance',
+                    actions: ['query', 'save'],
+                  },
+                ],
+              },
+              {
+                id: 'delete',
+                name: '删除',
+                permissions: [
+                  {
+                    permission: 'device-instance',
+                    actions: ['query', 'delete'],
+                  },
+                ],
+              },
+              {
+                id: 'update',
+                name: '编辑',
+                permissions: [
+                  {
+                    permission: 'rule-instance',
+                    actions: ['query', 'save'],
+                  },
+                ],
+              },
+              {
+                id: 'setting',
+                name: '下发',
+                permissions: [
+                  {
+                    permission: 'rule-instance',
+                    actions: ['query', 'save'],
+                  },
+                ],
+              },
+            ],
+          },
         ],
       },
     ],