xieyonghong 3 лет назад
Родитель
Сommit
ffacda2ac6

+ 1 - 1
src/pages/device/Instance/Detail/EdgeMap/mapTable/index.tsx

@@ -453,7 +453,7 @@ const MapTable = (props: Props) => {
               const array = value.requestList.filter((item: any) => item.channelId);
               const submitData = {
                 deviceId: deviceId,
-                provider: array[0].provider,
+                provider: array[0]?.provider,
                 requestList: array,
               };
               save(submitData);

+ 14 - 10
src/pages/device/Instance/Detail/EdgeMap/mapTree/index.tsx

@@ -81,17 +81,21 @@ const MapTree = (props: Props) => {
         onlyMessage('暂无属性映射', 'warning');
       }
     } else {
-      const res = await service.addDevice(props.addDevice);
-      if (res.status === 200) {
-        const resp = await service.saveMap(edgeId, {
-          deviceId: res.result.id,
-          provider: filterParms[0].provider,
-          requestList: filterParms,
-        });
-        if (resp.status === 200) {
-          onlyMessage('保存成功');
-          close();
+      if (filterParms && filterParms.length !== 0) {
+        const res = await service.addDevice(props.addDevice);
+        if (res.status === 200) {
+          const resp = await service.saveMap(edgeId, {
+            deviceId: res.result.id,
+            provider: filterParms[0]?.provider,
+            requestList: filterParms,
+          });
+          if (resp.status === 200) {
+            onlyMessage('保存成功');
+            close();
+          }
         }
+      } else {
+        onlyMessage('暂无属性映射', 'warning');
       }
     }
   };

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

@@ -22,7 +22,7 @@ export default (props: Props) => {
   const [value, setValue] = useState<any>(props.value || '');
   const [visible, setVisible] = useState<boolean>(false);
   const [objVisiable, setObjVisable] = useState<boolean>(false);
-  const [source, setSource] = useState<string>('');
+  const [source, setSource] = useState<string>('fixed');
   const [builtInList, setBuiltInList] = useState<any[]>([]);
 
   const sourceChangeEvent = async () => {
@@ -39,7 +39,7 @@ export default (props: Props) => {
   const onChange = (params: any) => {
     setValue(params);
     if (props.onChange) {
-      props.onChange(params);
+      props.onChange(params, source);
     }
   };
 
@@ -70,7 +70,7 @@ export default (props: Props) => {
           <Select
             value={value}
             style={{ width: '100%', textAlign: 'left' }}
-            options={props.record.options || []}
+            options={props.record?.options || []}
             fieldNames={{ label: 'text', value: 'value' }}
             placeholder={'请选择'}
             mode="multiple"
@@ -150,7 +150,7 @@ export default (props: Props) => {
             onChange={(e) => {
               setValue(e.target.value);
               if (props.onChange) {
-                props.onChange(e.target.value);
+                props.onChange(e.target.value, source);
               }
             }}
           />
@@ -161,7 +161,7 @@ export default (props: Props) => {
   const itemList: ItemProps[] = [
     {
       label: `手动输入`,
-      key: 'manual',
+      key: 'fixed',
       content: renderNode(props.type),
     },
     {
@@ -191,7 +191,7 @@ export default (props: Props) => {
         inputProps={{
           placeholder: '请选择',
         }}
-        tabKey={'manual'}
+        tabKey={'fixed'}
         itemList={itemList}
         value={value}
         onChange={(val: any, tabKey: any) => {

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

@@ -23,20 +23,20 @@ export default (props: Props) => {
   const [propertiesId, setPropertiesId] = useState<string | undefined>(undefined);
   const [propertiesValue, setPropertiesValue] = useState(undefined);
   const [propertiesType, setPropertiesType] = useState('');
-  const [source, setSource] = useState<string>('');
+  const [source, setSource] = useState<string>('fixed');
 
   useEffect(() => {
-    console.log(props.value);
+    // console.log(props.value);
     if (props.value) {
       if (props.properties && props.properties.length) {
         if (0 in props.value) {
           setPropertiesValue(props.value[0]);
         } else if ('undefined' in props.value) {
-          // setPropertiesKey(undefined);
           setPropertiesValue(undefined);
         } else {
+          console.log(Object.keys(props.value));
           Object.keys(props.value).forEach((key: string) => {
-            // setPropertiesKey(key);
+            setPropertiesId(key);
             setPropertiesValue(props.value[key].value);
             const propertiesItem = props.properties.find((item: any) => item.id === key);
             if (propertiesItem) {
@@ -46,13 +46,11 @@ export default (props: Props) => {
         }
       }
     } else {
-      // setPropertiesKey(undefined);
       setPropertiesValue(undefined);
     }
   }, [props.value, props.properties]);
 
   useEffect(() => {
-    // console.log(propertiesValue)
     if (props.onChange && propertiesValue) {
       const obj = {
         [propertiesId || 0]: {
@@ -69,8 +67,8 @@ export default (props: Props) => {
       <Col span={12}>
         <Select
           id={props.id}
-          value={props.value ? props.value[0] : undefined}
-          options={props.properties.filter((item) => {
+          value={props.value ? propertiesId : undefined}
+          options={props.properties?.filter((item) => {
             if (item.expands && item.expands.type) {
               return item.expands.type.includes('write');
             }
@@ -93,6 +91,7 @@ export default (props: Props) => {
             type={propertiesType}
             name={props.name}
             onChange={(value, sources) => {
+              console.log(value, sources);
               setPropertiesValue(value);
               setSource(sources);
             }}

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

@@ -14,7 +14,7 @@ interface Props {
 
 export default observer((props: Props) => {
   const [form] = Form.useForm();
-  const [deviceMessageType, setDeviceMessageType] = useState('WRITE_PROPERTY');
+  const [deviceMessageType, setDeviceMessageType] = useState('');
   const [properties, setProperties] = useState([]); // 物模型-属性
   const [propertiesId, setPropertiesId] = useState<string | undefined>(''); // 物模型-属性ID,用于串行
   const [functionList, setFunctionList] = useState<any>([]); // 物模型-功能
@@ -43,6 +43,8 @@ export default observer((props: Props) => {
   ];
 
   useEffect(() => {
+    // console.log(DeviceModel.message)
+    setDeviceMessageType(DeviceModel.message.messageType);
     if (DeviceModel.productDetail) {
       const metadata = JSON.parse(DeviceModel.productDetail?.metadata || '{}');
       setProperties(metadata.properties);
@@ -80,12 +82,18 @@ export default observer((props: Props) => {
 
   return (
     <div>
-      <Form form={form} layout={'vertical'}>
+      <Form
+        form={form}
+        layout={'vertical'}
+        initialValues={{
+          message: DeviceModel.message,
+        }}
+      >
         <Form.Item
-          name={['device', 'message', 'messageType']}
+          name={['message', 'messageType']}
           label="动作类型"
           required
-          initialValue="WRITE_PROPERTY"
+          // initialValue="WRITE_PROPERTY"
         >
           <TopCard
             typeList={TypeList}
@@ -97,7 +105,7 @@ export default observer((props: Props) => {
         {deviceMessageType === 'INVOKE_FUNCTION' && (
           <>
             <Form.Item
-              name={['device', 'message', 'functionId']}
+              name={['message', 'functionId']}
               label="功能调用"
               rules={[{ required: true, message: '请选择功能' }]}
             >
@@ -118,7 +126,7 @@ export default observer((props: Props) => {
             </Form.Item>
             {functionId && (
               <Form.Item
-                name={['device', 'message', 'inputs']}
+                name={['message', 'inputs']}
                 rules={[{ required: true, message: '请输入功能值' }]}
               >
                 <FunctionCall
@@ -132,7 +140,7 @@ export default observer((props: Props) => {
         )}
         {deviceMessageType === 'READ_PROPERTY' && (
           <Form.Item
-            name={['device', 'message', 'properties']}
+            name={['message', 'properties']}
             label="读取属性"
             rules={[{ required: true, message: '请选择读取属性' }]}
           >
@@ -141,14 +149,13 @@ export default observer((props: Props) => {
         )}
         {deviceMessageType === 'WRITE_PROPERTY' && (
           <Form.Item
-            name={['device', 'message', 'properties']}
+            name={['message', 'properties']}
             label="设置属性"
             rules={[{ required: true, message: '请选择属性' }]}
           >
             <WriteProperty properties={properties} name={props.name} />
           </Form.Item>
         )}
-        {/* {deviceMessageType === 'WRITE_PROPERTY' && <WriteProperty properties={properties} />} */}
       </Form>
     </div>
   );

+ 37 - 48
src/pages/rule-engine/Scene/Save/action/DeviceOutput/device/index.tsx

@@ -24,6 +24,7 @@ import Tag from './Tag';
 
 interface Props {
   name: number;
+  parallel: boolean;
 }
 
 export default observer((props: Props) => {
@@ -35,6 +36,7 @@ export default observer((props: Props) => {
   const selector = Form.useWatch('selector', form);
   const [tagList, setTagList] = useState([]);
   const [list, setList] = useState<any>([]);
+  const [isFirst, setIsFirst] = useState(true);
 
   const TypeList = [
     {
@@ -259,22 +261,12 @@ export default observer((props: Props) => {
     },
   ];
 
-  const isParallel = () => {
-    const array = FormModel.current.actions?.find((item) => 'terms' in item);
-    if (array && builtInList.length > 0) {
-      return true;
-    } else {
-      return false;
-    }
-  };
-
   const filterTree = (nodes: any[]) => {
     if (!nodes?.length) {
       return nodes;
     }
     return nodes.filter((it) => {
       if (it.children.find((item: any) => item.id.indexOf('deviceId') > -1)) {
-        // console.log(it.children.find((item: any) => item.id.indexOf('deviceId') > -1))
         return true;
       }
       return false;
@@ -291,33 +283,34 @@ export default observer((props: Props) => {
       }
     });
   };
+
   const filterType = async () => {
-    // console.log('',FormModel);
+    const _list = TypeList.filter((item) => item.value === 'fixed');
     if (FormModel.current.trigger?.type === 'device') {
+      //关系
       const res = await getRelations();
-      if (res.status === 200 && res.result.length === 0) {
-        const array = TypeList.filter((item) => item.value !== 'relation');
-        setList(array);
-      } else {
-        setList(TypeList);
+      if (res.status === 200 && res.result.length !== 0) {
+        const array = TypeList.filter((item) => item.value === 'relation');
+        _list.push(...array);
       }
+      //标签
       const tag = JSON.parse(DeviceModel.productDetail?.metadata || '{}')?.tags;
-      console.log(tag, 'tag');
       if (!tag) {
-        const array = TypeList.filter((item) => item.value !== 'tag');
-        setList(array);
-      } else {
-        setList(TypeList);
+        const array = TypeList.filter((item) => item.value === 'tag');
+        _list.push(...array);
+      }
+      //变量
+      if (builtInList.length !== 0 && !props.parallel) {
+        const array = TypeList.filter((item) => item.value === 'variable');
+        _list.push(...array);
       }
+      setList(_list);
     } else {
-      const arr = TypeList.filter((item) => item.value !== 'relation' && item.value !== 'tag');
-      const arr1 = TypeList.filter((item) => item.value === 'fixed');
-      // isParallel()? setList(arr1):setList(arr)
-      if (isParallel()) {
-        setList(arr1);
-      } else {
-        setList(arr);
+      if (builtInList.length !== 0 && !props.parallel) {
+        const array = TypeList.filter((item) => item.value === 'variable');
+        _list.push(...array);
       }
+      setList(_list);
     }
   };
 
@@ -361,16 +354,20 @@ export default observer((props: Props) => {
                   type: 'radio',
                   selectedRowKeys: [DeviceModel.deviceId],
                   onChange: (_, selectedRows) => {
-                    if (selectedRows.length) {
-                      const item = selectedRows?.[0];
-                      DeviceModel.deviceId = item.id;
-                      DeviceModel.deviceDetail = item;
-                      DeviceModel.selectorValues = [
-                        { value: DeviceModel.deviceId, name: item.name },
-                      ];
+                    if (!isFirst) {
+                      if (selectedRows.length) {
+                        const item = selectedRows?.[0];
+                        DeviceModel.deviceId = item.id;
+                        DeviceModel.deviceDetail = item;
+                        DeviceModel.selectorValues = [
+                          { value: DeviceModel.deviceId, name: item.name },
+                        ];
+                      } else {
+                        DeviceModel.deviceId = '';
+                        DeviceModel.selectorValues = [];
+                      }
                     } else {
-                      DeviceModel.deviceId = '';
-                      DeviceModel.selectorValues = [];
+                      setIsFirst(false);
                     }
                   },
                 }}
@@ -457,16 +454,16 @@ export default observer((props: Props) => {
       form.setFieldsValue({ selector: DeviceModel.selector });
     }
     sourceChangeEvent();
+    console.log('-----deviceid-----', DeviceModel.deviceId);
   }, []);
 
   useEffect(() => {
     if (DeviceModel.productDetail) {
       const metadata = JSON.parse(DeviceModel.productDetail?.metadata || '{}');
       setTagList(metadata.tags);
-      // console.log(metadata.tags)
       filterType();
     }
-  }, [DeviceModel.productDetail]);
+  }, [DeviceModel.productDetail, builtInList]);
 
   useEffect(() => {
     DeviceModel.selector = selector;
@@ -478,16 +475,8 @@ export default observer((props: Props) => {
         <ExclamationCircleOutlined className="device-title-icon" />
         <span>自定义选择当前产品下的任意设备</span>
       </div>
-
-      {/* {isParallel() && (
-        <Form form={form} layout={'vertical'}>
-          <Form.Item name="selector" label="选择方式" required>
-            <TopCard typeList={TypeList} />
-          </Form.Item>
-        </Form>
-      )} */}
       <Form form={form} layout={'vertical'}>
-        <Form.Item name="selector" label="选择方式" required>
+        <Form.Item name="selector" label="选择方式" required hidden={list.length === 1}>
           <TopCard typeList={list} />
         </Form.Item>
         {contentRender(selector)}

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

@@ -1,5 +1,5 @@
 import { Modal, Button, Steps } from 'antd';
-import { useEffect, useRef, useState } from 'react';
+import { useEffect, useRef } from 'react';
 import { observer } from '@formily/react';
 import Device from './device';
 import Product from './product';
@@ -9,7 +9,6 @@ import './index.less';
 import DeviceModel from './model';
 import { onlyMessage } from '@/utils/util';
 import { ActionsDeviceProps } from '../../../typings';
-// import { FormModel } from '../..';
 
 export const service = new Service<any>('');
 
@@ -18,23 +17,22 @@ interface Props {
   save: (data: any, _options?: any) => void;
   cancel: () => void;
   name: number;
+  parallel: boolean;
 }
 
 export default observer((props: Props) => {
-  const [open, setOpen] = useState<boolean>(true);
-  // const [data, setData] = useState<any>({})
   const formRef = useRef<any>();
 
   DeviceModel.steps = [
     {
       key: 'product',
       title: '选择产品',
-      content: <Product />,
+      content: <Product productId={props.value?.productId} />,
     },
     {
       key: 'device',
       title: '选择设备',
-      content: <Device name={props.name} />,
+      content: <Device name={props.name} parallel={props.parallel} />,
     },
     {
       key: 'action',
@@ -73,7 +71,7 @@ export default observer((props: Props) => {
       source: DeviceModel.source,
       selectorValues: DeviceModel.selectorValues,
       productId: DeviceModel.productId,
-      message: value.device.message,
+      message: value.message,
     };
     // console.log(item, value);
 
@@ -87,19 +85,19 @@ export default observer((props: Props) => {
       taglist: [],
     };
     _options.name = DeviceModel.deviceDetail.name;
-    const _type = value.device.message.messageType;
+    const _type = value.message.messageType;
     if (_type === 'INVOKE_FUNCTION') {
       _options.type = '执行';
-      _options.properties = value.device.message.functionId;
+      _options.properties = value.message.functionId;
     }
     if (_type === 'READ_PROPERTY') {
       _options.type = '读取';
-      _options.properties = value.device.message.properties?.[0];
+      _options.properties = value.message.properties?.[0];
       // _options.name = DeviceModel.selectorValues[0].name;
     }
     if (_type === 'WRITE_PROPERTY') {
       _options.type = '设置';
-      _options.properties = Object.keys(value.device.message.properties)?.[0];
+      _options.properties = Object.keys(value.message.properties)?.[0];
       // _options.name = DeviceModel.selectorValues[0].name;
     }
     if (_options.selector === 'tag') {
@@ -110,30 +108,48 @@ export default observer((props: Props) => {
       }));
       // console.log(_options.taglist, 'taglist')
     }
-    console.log(_options);
-    console.log(DeviceModel.deviceDetail.name);
-    // console.log('device', item);
+    console.log(item);
     props.save(item, _options);
-    // FormModel.actions[props.name].options = _options;
     DeviceModel.current = 0;
   };
 
   useEffect(() => {
-    console.log(props.value);
+    if (props.value) {
+      console.log('----------', props.value);
+      DeviceModel.selector = props.value.selector;
+      DeviceModel.productId = props.value.productId;
+      DeviceModel.selector = props.value.selector;
+      DeviceModel.selectorValues = props.value.selectorValues;
+      DeviceModel.message = props.value.message;
+      DeviceModel.deviceId =
+        props.value.selector === 'fixed'
+          ? props.value.selectorValues?.map((item: any) => item.value)[0]
+          : 'deviceId';
+    }
   }, [props.value]);
 
   return (
     <Modal
       title={'执行动作'}
-      open={open}
+      open
       width={800}
       onCancel={() => {
-        setOpen(false);
+        props.cancel();
+        DeviceModel.current = 0;
       }}
       maskClosable={false}
       footer={
         <div className="steps-action">
-          {DeviceModel.current === 0 && <Button onClick={() => {}}>取消</Button>}
+          {DeviceModel.current === 0 && (
+            <Button
+              onClick={() => {
+                props.cancel();
+                DeviceModel.current = 0;
+              }}
+            >
+              取消
+            </Button>
+          )}
           {DeviceModel.current > 0 && (
             <Button style={{ margin: '0 8px' }} onClick={() => prev()}>
               上一步

+ 2 - 0
src/pages/rule-engine/Scene/Save/action/DeviceOutput/model.ts

@@ -21,6 +21,7 @@ type ModelType = {
   upperKey: string;
   source: string;
   relationName: string;
+  message: any;
 };
 
 const DeviceModel = model<ModelType>({
@@ -37,6 +38,7 @@ const DeviceModel = model<ModelType>({
   upperKey: '',
   source: 'fixed',
   relationName: '',
+  message: {},
 });
 
 export default DeviceModel;

+ 18 - 4
src/pages/rule-engine/Scene/Save/action/DeviceOutput/product/index.tsx

@@ -1,7 +1,7 @@
 import { ProTableCard } from '@/components';
 import SearchComponent from '@/components/SearchComponent';
 import { ProductItem } from '@/pages/device/Product/typings';
-import { useRef, useState } from 'react';
+import { useEffect, useRef, useState } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import { service } from '@/pages/device/Product/index';
 import { SceneProductCard } from '@/components/ProTableCard/CardItems/product';
@@ -12,7 +12,11 @@ import { service as deptService } from '@/pages/system/Department';
 import DeviceModel from '../model';
 import { observer } from '@formily/reactive-react';
 
-export default observer(() => {
+interface Props {
+  productId: string;
+}
+
+export default observer((props: Props) => {
   const actionRef = useRef<ActionType>();
   const intl = useIntl();
   const [searchParam, setSearchParam] = useState({});
@@ -189,6 +193,17 @@ export default observer(() => {
           }),
     },
   ];
+
+  useEffect(() => {
+    if (props.productId) {
+      service.detail(props.productId).then((res) => {
+        if (res.status === 200) {
+          DeviceModel.productDetail = res.result;
+        }
+      });
+    }
+  }, []);
+
   return (
     <div>
       <SearchComponent
@@ -219,8 +234,7 @@ export default observer(() => {
           rowSelection={{
             type: 'radio',
             selectedRowKeys: [DeviceModel.productId],
-            onChange: (selectedRowKeys, selectedRows) => {
-              // console.log(selectedRowKeys,selectedRows)
+            onChange: (_, selectedRows) => {
               DeviceModel.productId = selectedRows.map((item) => item.id)?.[0];
               DeviceModel.productDetail = selectedRows?.[0];
             },

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

@@ -331,7 +331,7 @@ export default (props: ItemProps) => {
             props.onUpdate(data, options);
             setVisible(false);
           }}
-          type={props.type}
+          parallel={props.parallel}
         />
       )}
       {triggerVisible && (

+ 5 - 12
src/pages/rule-engine/Scene/Save/action/Modal/add.tsx

@@ -2,7 +2,7 @@ import { Modal, Form } from 'antd';
 import ActionsTypeComponent from '@/pages/rule-engine/Scene/Save/components/TriggerWay/actionsType';
 import { useEffect, useState } from 'react';
 import Notify from '../notify';
-import type { ActionsType, ParallelType } from '@/pages/rule-engine/Scene/typings';
+import type { ActionsType } from '@/pages/rule-engine/Scene/typings';
 import Device from '../DeviceOutput';
 import Delay from '../Delay';
 
@@ -11,7 +11,8 @@ interface Props {
   save: (data: any, options?: any) => void;
   data: Partial<ActionsType>;
   name: number;
-  type: ParallelType;
+  // type: ParallelType;
+  parallel: boolean;
 }
 
 export default (props: Props) => {
@@ -34,15 +35,6 @@ export default (props: Props) => {
             value={props.data?.device}
             save={(data: any, options: any) => {
               setActionType('');
-              console.log('Device', data);
-              // props.save(data, options);
-              // console.log('device-------------', {
-              //   type: 'device',
-              //   key: props.data.key || `action_${props.name}`,
-              //   device: {
-              //     ...data,
-              //   },
-              // });
               props.save(
                 {
                   type: 'device',
@@ -58,6 +50,7 @@ export default (props: Props) => {
             cancel={() => {
               setActionType('');
             }}
+            parallel={props.parallel}
           />
         );
       case 'notify':
@@ -131,7 +124,7 @@ export default (props: Props) => {
           required
           rules={[{ required: true, message: '请选择类型' }]}
         >
-          <ActionsTypeComponent type={props.type} />
+          <ActionsTypeComponent parallel={props.parallel} />
         </Form.Item>
       </Form>
       {actionTypeComponent(actionType)}

+ 1 - 1
src/pages/rule-engine/Scene/Save/action/device/readProperty.tsx

@@ -13,7 +13,7 @@ export default (props: ReadPropertyProps) => {
     <Select
       id={props.id}
       value={props.value ? props.value[0] : undefined}
-      options={props.properties.filter((item) => {
+      options={props.properties?.filter((item) => {
         if (item.expands && item.expands.type) {
           return item.expands.type.includes('read');
         }

+ 4 - 3
src/pages/rule-engine/Scene/Save/components/TriggerWay/actionsType.tsx

@@ -1,7 +1,7 @@
 import { useEffect, useState } from 'react';
 import classNames from 'classnames';
 import './index.less';
-import { ParallelType } from '../../../typings';
+// import { ParallelType } from '../../../typings';
 
 interface ActionsTypeProps {
   value?: string;
@@ -9,7 +9,8 @@ interface ActionsTypeProps {
   onChange?: (type: string) => void;
   onSelect?: (type: string) => void;
   disabled?: boolean;
-  type: ParallelType;
+  // type: ParallelType;
+  parallel: boolean; //并行true
 }
 
 export enum ActionsTypeEnum {
@@ -71,7 +72,7 @@ export default (props: ActionsTypeProps) => {
   return (
     <div className={classNames('trigger-way-warp', props.className, { disabled: props.disabled })}>
       {TypeList.map((item) =>
-        props.type === 'parallel' && item.value === 'delay' ? null : (
+        props.parallel && item.value === 'delay' ? null : (
           <div
             key={item.value}
             className={classNames('trigger-way-item', {