Przeglądaj źródła

fix: 设备输出

Wzyyy98 3 lat temu
rodzic
commit
8a3019f1b6

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

@@ -44,13 +44,10 @@ export default (props: Props) => {
   };
   };
 
 
   useEffect(() => {
   useEffect(() => {
-    if (props.onChange) {
-      props.onChange(value, source);
-    }
     if (source === 'upper') {
     if (source === 'upper') {
       sourceChangeEvent();
       sourceChangeEvent();
     }
     }
-  }, [source, value]);
+  }, [source]);
 
 
   const renderNode = (type: string) => {
   const renderNode = (type: string) => {
     switch (type) {
     switch (type) {
@@ -198,8 +195,12 @@ export default (props: Props) => {
         itemList={itemList}
         itemList={itemList}
         value={value}
         value={value}
         onChange={(val: any, tabKey: any) => {
         onChange={(val: any, tabKey: any) => {
+          // console.log(val,tabKey)
           setValue(val);
           setValue(val);
           setSource(tabKey);
           setSource(tabKey);
+          if (props.onChange) {
+            props.onChange(val, tabKey);
+          }
         }}
         }}
         type={props.type}
         type={props.type}
       />
       />

+ 245 - 0
src/pages/rule-engine/Scene/Save/action/DeviceOutput/device/Tag.tsx

@@ -0,0 +1,245 @@
+import { Button, Col, DatePicker, Input, InputNumber, Row, Select, Space } from 'antd';
+import { useEffect, useState } from 'react';
+import moment from 'moment';
+import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
+
+interface TagModalProps {
+  tagData: any[];
+  value?: any[];
+  onChange?: (value: any[]) => void;
+  id?: string;
+}
+
+/**
+ * 数据格式 [{"value":{"key":"value"},"name":"标签名称"}]
+ * @param props
+ */
+export default (props: TagModalProps) => {
+  const [tagList, setTagList] = useState<any[]>([{}]);
+  const [options, setOptions] = useState<any[]>([]);
+
+  const handleItem = (data: any) => {
+    return {
+      ...data,
+      valueType: data.valueType ? data.valueType.type : '-',
+      format: data.valueType ? data.valueType.format : undefined,
+      options: data.valueType ? data.valueType.elements : undefined,
+      value: data.value,
+    };
+  };
+
+  const onChange = () => {
+    const newValue = tagList
+      .filter((item) => !!item.value)
+      .map((item: any) => {
+        return {
+          column: item.id,
+          type: item.type,
+          value: item.value,
+        };
+      });
+    console.log();
+    if (props.onChange) {
+      props.onChange([{ value: newValue, name: '标签' }]);
+    }
+  };
+
+  useEffect(() => {
+    setOptions(
+      props.tagData?.map((item: any) => {
+        return { label: item.name, value: item.id, ...item };
+      }),
+    );
+  }, [props.tagData]);
+
+  useEffect(() => {
+    if (
+      props.value &&
+      props.value[0] &&
+      props.value[0].name &&
+      props.tagData &&
+      props.tagData.length
+    ) {
+      const names: string[] = [];
+      const newTagList = props.value[0].value
+        .filter((valueItem: any) => {
+          return props.tagData.some((item) => valueItem.column === item.id);
+        })
+        .map((valueItem: any) => {
+          const oldItem = props.tagData.find((item) => item.id === valueItem.column);
+          if (oldItem) {
+            names.push(oldItem.name);
+            return {
+              ...handleItem(oldItem),
+              value: valueItem.value,
+              type: valueItem.type,
+            };
+          }
+          return valueItem;
+        });
+      //   setNameList(names);
+      setTagList(newTagList);
+    } else {
+      setTagList([{}]);
+    }
+  }, [props.value, props.tagData]);
+
+  const getItemNode = (record: any) => {
+    const type = record.valueType;
+    const name = record.name;
+
+    switch (type) {
+      case 'enum':
+        return (
+          <Select
+            value={record.value}
+            style={{ width: '100%', textAlign: 'left' }}
+            options={record.options}
+            fieldNames={{ label: 'text', value: 'value' }}
+            placeholder={'请选择' + name}
+            onChange={(key) => {
+              record.value = key;
+            }}
+          />
+        );
+      case 'boolean':
+        return (
+          <Select
+            value={record.value}
+            style={{ width: '100%', textAlign: 'left' }}
+            options={[
+              { label: 'true', value: true },
+              { label: 'false', value: false },
+            ]}
+            placeholder={'请选择' + name}
+            onChange={(key) => {
+              record.value = key;
+            }}
+          />
+        );
+      case 'int':
+      case 'long':
+      case 'float':
+      case 'double':
+        return (
+          <InputNumber
+            value={record.value}
+            style={{ width: '100%' }}
+            placeholder={'请输入' + name}
+            onChange={(key) => {
+              record.value = key;
+            }}
+          />
+        );
+      case 'date':
+        return (
+          <>
+            {
+              // @ts-ignore
+              <DatePicker
+                value={record.value && moment(record.value, 'YYYY-MM-DD HH:mm:ss')}
+                format={record.format || 'YYYY-MM-DD HH:mm:ss'}
+                style={{ width: '100%' }}
+                onChange={(_, date) => {
+                  record.value = date;
+                }}
+              />
+            }
+          </>
+        );
+      default:
+        return (
+          <Input
+            value={record.value}
+            placeholder={'请输入标签值'}
+            onChange={(e) => {
+              record.value = e.target.value;
+            }}
+          />
+        );
+    }
+  };
+
+  return (
+    <>
+      <div
+        onChange={() => {
+          onChange();
+        }}
+      >
+        {tagList.map((tag, index) => (
+          <Row gutter={12} key={tag.id || index} style={{ marginBottom: 12 }}>
+            <Col span={4}>
+              {index === 0 ? (
+                <span>标签选择</span>
+              ) : (
+                <Select
+                  value={tag.type}
+                  options={[
+                    { label: '并且', value: 'and' },
+                    { label: '或者', value: 'or' },
+                  ]}
+                  style={{ width: '100%' }}
+                  onSelect={(key: string) => {
+                    const indexItem = tagList[index];
+                    indexItem.type = key;
+                    tagList[index] = indexItem;
+                    setTagList([...tagList]);
+                  }}
+                />
+              )}
+            </Col>
+            <Col span={16}>
+              <Row gutter={12}>
+                <Col flex="120px">
+                  <Select
+                    value={tag.id}
+                    style={{ width: '120px' }}
+                    options={options}
+                    onSelect={(_: any, data: any) => {
+                      const newList = [...tagList];
+                      const indexType = newList[index].type;
+                      newList.splice(
+                        index,
+                        1,
+                        handleItem({ ...data, value: undefined, type: indexType }),
+                      );
+                      setTagList(newList);
+                    }}
+                    placeholder={'请选择标签'}
+                  />
+                </Col>
+                <Col flex={'auto'}>{getItemNode(tag)}</Col>
+              </Row>
+            </Col>
+            <Col span={4}>
+              <Space>
+                <Button
+                  style={{ padding: '0 8px' }}
+                  onClick={() => {
+                    setTagList([...tagList, { type: 'and' }]);
+                  }}
+                >
+                  <PlusOutlined />
+                </Button>
+                {tagList.length !== 1 && (
+                  <Button
+                    style={{ padding: '0 8px' }}
+                    onClick={() => {
+                      const newTagList = [...tagList];
+                      newTagList.splice(index, 1);
+                      setTagList(newTagList);
+                    }}
+                    danger
+                  >
+                    <DeleteOutlined />
+                  </Button>
+                )}
+              </Space>
+            </Col>
+          </Row>
+        ))}
+      </div>
+    </>
+  );
+};

+ 205 - 86
src/pages/rule-engine/Scene/Save/action/DeviceOutput/device/index.tsx

@@ -18,6 +18,9 @@ import { ExclamationCircleOutlined } from '@ant-design/icons';
 import { FormModel } from '../../..';
 import { FormModel } from '../../..';
 import { BuiltInParamsHandleTreeData } from '@/pages/rule-engine/Scene/Save/components/BuiltInParams';
 import { BuiltInParamsHandleTreeData } from '@/pages/rule-engine/Scene/Save/components/BuiltInParams';
 import { queryBuiltInParams } from '@/pages/rule-engine/Scene/Save/action/service';
 import { queryBuiltInParams } from '@/pages/rule-engine/Scene/Save/action/service';
+import RelationSelect from '../../device/relationSelect';
+import { getRelations } from '@/pages/rule-engine/Scene/Save/action/service';
+import Tag from './Tag';
 
 
 interface Props {
 interface Props {
   name: number;
   name: number;
@@ -28,13 +31,27 @@ export default observer((props: Props) => {
   const intl = useIntl();
   const intl = useIntl();
   const [searchParam, setSearchParam] = useState({});
   const [searchParam, setSearchParam] = useState({});
   const [form] = Form.useForm();
   const [form] = Form.useForm();
-  const [type, setType] = useState<string>('');
   const [builtInList, setBuiltInList] = useState<any[]>([]);
   const [builtInList, setBuiltInList] = useState<any[]>([]);
+  const selector = Form.useWatch('selector', form);
+  const [tagList, setTagList] = useState([]);
+  const [list, setList] = useState<any>([]);
 
 
   const TypeList = [
   const TypeList = [
     {
     {
       label: '自定义',
       label: '自定义',
-      value: 'custom',
+      value: 'fixed',
+      image: require('/public/images/scene/device-custom.png'),
+      tip: '自定义选择当前产品下的任意设备',
+    },
+    {
+      label: '按关系',
+      value: 'relation',
+      image: require('/public/images/scene/device-custom.png'),
+      tip: '自定义选择当前产品下的任意设备',
+    },
+    {
+      label: '按标签',
+      value: 'tag',
       image: require('/public/images/scene/device-custom.png'),
       image: require('/public/images/scene/device-custom.png'),
       tip: '自定义选择当前产品下的任意设备',
       tip: '自定义选择当前产品下的任意设备',
     },
     },
@@ -216,9 +233,9 @@ export default observer((props: Props) => {
             paging: false,
             paging: false,
           })
           })
           .then((resp) => {
           .then((resp) => {
-            const formatValue = (list: any[]) => {
+            const formatValue = (lists: any[]) => {
               const _list: any[] = [];
               const _list: any[] = [];
-              list.forEach((item) => {
+              lists.forEach((item) => {
                 if (item.children) {
                 if (item.children) {
                   item.children = formatValue(item.children);
                   item.children = formatValue(item.children);
                 }
                 }
@@ -271,107 +288,209 @@ export default observer((props: Props) => {
         const _data = BuiltInParamsHandleTreeData(res.result);
         const _data = BuiltInParamsHandleTreeData(res.result);
         const array = filterTree(_data);
         const array = filterTree(_data);
         setBuiltInList(array);
         setBuiltInList(array);
-        // console.log(array)
       }
       }
     });
     });
   };
   };
+  const filterType = async () => {
+    console.log(FormModel);
+    if (FormModel.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);
+      }
+      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);
+      }
+    } 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);
+      }
+    }
+  };
 
 
-  useEffect(() => {
-    // console.log(FormModel, isParallel())
-    sourceChangeEvent();
-    setType('custom');
-  }, []);
-
-  return (
-    <div>
-      <div className="device-title">
-        <ExclamationCircleOutlined className="device-title-icon" />
-        <span>自定义选择当前产品下的任意设备</span>
-      </div>
-      {isParallel() && (
-        <Form form={form} layout={'vertical'}>
-          <Form.Item name="type" label="选择方式" required>
-            <TopCard
-              typeList={TypeList}
-              value={'custom'}
+  const contentRender = (type?: string) => {
+    switch (type) {
+      //自定义
+      case 'fixed':
+        return (
+          <>
+            <SearchComponent
+              field={columns}
+              model={'simple'}
+              enableSave={false}
+              onSearch={async (data) => {
+                actionRef.current?.reset?.();
+                setSearchParam(data);
+              }}
+              target="device"
+              defaultParam={[
+                {
+                  terms: [
+                    {
+                      column: 'productId',
+                      value: DeviceModel.productId,
+                    },
+                  ],
+                },
+              ]}
+            />
+            <div>
+              <ProTableCard<DeviceInstance>
+                actionRef={actionRef}
+                columns={columns}
+                rowKey="id"
+                search={false}
+                gridColumn={2}
+                columnEmptyText={''}
+                onlyCard={true}
+                tableAlertRender={false}
+                rowSelection={{
+                  type: 'radio',
+                  selectedRowKeys: [DeviceModel.deviceId],
+                  onChange: (_, selectedRows) => {
+                    if (selectedRows.length) {
+                      const item = selectedRows?.[0];
+                      DeviceModel.deviceId = item.id;
+                      DeviceModel.selectorValues = [
+                        { value: DeviceModel.deviceId, name: item.name },
+                      ];
+                    } else {
+                      DeviceModel.deviceId = '';
+                      DeviceModel.selectorValues = [];
+                    }
+                  },
+                }}
+                request={(params) =>
+                  service.query({
+                    ...params,
+                    sorts: [{ name: 'createTime', order: 'desc' }],
+                  })
+                }
+                params={searchParam}
+                cardRender={(record) => (
+                  <SceneDeviceCard showBindBtn={false} showTool={false} {...record} />
+                )}
+                height={'none'}
+              />
+            </div>
+          </>
+        );
+      case 'relation':
+        return (
+          <Form.Item
+            name="selectorValues"
+            label="关系"
+            rules={[{ required: true, message: '请选择关系人' }]}
+          >
+            <RelationSelect
+              onChange={(value, options) => {
+                // console.log(value,options)
+                if (value) {
+                  DeviceModel.deviceId = 'deviceId';
+                  DeviceModel.source = 'upper';
+                  DeviceModel.selectorValues = value;
+                  DeviceModel.upperKey = 'deviceId';
+                  DeviceModel.relationName = options.label;
+                }
+              }}
+            />
+          </Form.Item>
+        );
+      case 'tag':
+        return (
+          <Form.Item
+            name="selectorValues"
+            // label='标签'
+            rules={[{ required: true, message: '请选择标签' }]}
+          >
+            <Tag
+              tagData={tagList}
               onChange={(value) => {
               onChange={(value) => {
-                setType(value);
+                console.log(value);
+                if (value) {
+                  DeviceModel.deviceId = 'deviceId';
+                  DeviceModel.source = 'fixed';
+                  DeviceModel.selectorValues = value;
+                }
               }}
               }}
             />
             />
           </Form.Item>
           </Form.Item>
-          {type === 'variable' && (
-            <Form.Item name="deviceId" label="变量" required>
+        );
+      default:
+        return (
+          <>
+            <Form.Item name="selectorValues" label="变量" required>
               <TreeSelect
               <TreeSelect
                 style={{ width: '100%', height: '100%' }}
                 style={{ width: '100%', height: '100%' }}
                 treeData={builtInList}
                 treeData={builtInList}
                 fieldNames={{ label: 'name', value: 'id' }}
                 fieldNames={{ label: 'name', value: 'id' }}
                 placeholder={'请选择参数'}
                 placeholder={'请选择参数'}
                 onSelect={(value: any, node: any) => {
                 onSelect={(value: any, node: any) => {
-                  // console.log(value,node)
-                  DeviceModel.deviceId = [value];
+                  console.log(value, node);
+                  DeviceModel.deviceId = value;
                   DeviceModel.deviceDetail = node;
                   DeviceModel.deviceDetail = node;
+                  DeviceModel.selectorValues = [{ value: value, name: node.description }];
                 }}
                 }}
               />
               />
             </Form.Item>
             </Form.Item>
-          )}
+          </>
+        );
+    }
+  };
+
+  useEffect(() => {
+    if (form) {
+      form.setFieldsValue({ selector: DeviceModel.selector });
+    }
+    sourceChangeEvent();
+  }, []);
+
+  useEffect(() => {
+    if (DeviceModel.productDetail) {
+      const metadata = JSON.parse(DeviceModel.productDetail?.metadata || '{}');
+      setTagList(metadata.tags);
+      // console.log(metadata.tags)
+      filterType();
+    }
+  }, [DeviceModel.productDetail]);
+
+  useEffect(() => {
+    DeviceModel.selector = selector;
+  }, [selector]);
+
+  return (
+    <div>
+      <div className="device-title">
+        <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>
-      )}
-      {type === 'custom' && (
-        <>
-          <SearchComponent
-            field={columns}
-            model={'simple'}
-            enableSave={false}
-            onSearch={async (data) => {
-              actionRef.current?.reset?.();
-              setSearchParam(data);
-            }}
-            target="device"
-            defaultParam={[
-              {
-                terms: [
-                  {
-                    column: 'productId',
-                    value: DeviceModel.productId[0],
-                  },
-                ],
-              },
-            ]}
-          />
-          <div>
-            <ProTableCard<DeviceInstance>
-              actionRef={actionRef}
-              columns={columns}
-              rowKey="id"
-              search={false}
-              gridColumn={2}
-              columnEmptyText={''}
-              onlyCard={true}
-              tableAlertRender={false}
-              rowSelection={{
-                type: 'radio',
-                selectedRowKeys: DeviceModel.deviceId,
-                onChange: (selectedRowKeys, selectedRows) => (
-                  // console.log(selectedRowKeys)
-                  (DeviceModel.deviceId = selectedRowKeys),
-                  (DeviceModel.deviceDetail = selectedRows?.[0])
-                ),
-              }}
-              request={(params) =>
-                service.query({
-                  ...params,
-                  sorts: [{ name: 'createTime', order: 'desc' }],
-                })
-              }
-              params={searchParam}
-              cardRender={(record) => (
-                <SceneDeviceCard showBindBtn={false} showTool={false} {...record} />
-              )}
-              height={'none'}
-            />
-          </div>
-        </>
-      )}
+      )} */}
+      <Form form={form} layout={'vertical'}>
+        <Form.Item name="selector" label="选择方式" required>
+          <TopCard typeList={list} />
+        </Form.Item>
+        {contentRender(selector)}
+      </Form>
     </div>
     </div>
   );
   );
 });
 });

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

@@ -9,6 +9,7 @@ import './index.less';
 import DeviceModel from './model';
 import DeviceModel from './model';
 import { onlyMessage } from '@/utils/util';
 import { onlyMessage } from '@/utils/util';
 import { ActionsDeviceProps } from '../../../typings';
 import { ActionsDeviceProps } from '../../../typings';
+import { FormModel } from '../..';
 
 
 export const service = new Service<any>('');
 export const service = new Service<any>('');
 
 
@@ -48,16 +49,6 @@ export default observer((props: Props) => {
       ),
       ),
     },
     },
   ];
   ];
-
-  // const handleOptions = ()=>{
-  //   const _options: any = {
-  //     name: '', // 名称
-  //     onlyName: false,
-  //     type: '', // 触发类型
-  //     action: DeviceModel.options.action,
-  //   };
-  // }
-
   const next = () => {
   const next = () => {
     if (
     if (
       (DeviceModel.current === 0 && DeviceModel.productId.length !== 0) ||
       (DeviceModel.current === 0 && DeviceModel.productId.length !== 0) ||
@@ -78,15 +69,10 @@ export default observer((props: Props) => {
   const save = async () => {
   const save = async () => {
     const value = await formRef.current?.validateFields();
     const value = await formRef.current?.validateFields();
     const item = {
     const item = {
-      selector: 'fixed',
-      source: 'fixed',
-      selectorValues: [
-        {
-          value: DeviceModel.deviceDetail.id,
-          name: DeviceModel.deviceDetail.name,
-        },
-      ],
-      productId: DeviceModel.productId[0],
+      selector: DeviceModel.selector,
+      source: DeviceModel.source,
+      selectorValues: DeviceModel.selectorValues,
+      productId: DeviceModel.productId,
       message: value,
       message: value,
     };
     };
     console.log(item, value);
     console.log(item, value);
@@ -95,6 +81,10 @@ export default observer((props: Props) => {
       name: '', //设备名称
       name: '', //设备名称
       type: '', //类型
       type: '', //类型
       properties: '', //属性功能
       properties: '', //属性功能
+      selector: DeviceModel.selector, //选择器标识
+      productName: DeviceModel.productDetail.name,
+      relationName: DeviceModel.relationName,
+      taglist: [],
     };
     };
     _options.name = DeviceModel.deviceDetail.name;
     _options.name = DeviceModel.deviceDetail.name;
     const _type = value.device.message.messageType;
     const _type = value.device.message.messageType;
@@ -110,9 +100,19 @@ export default observer((props: Props) => {
       _options.type = '设置';
       _options.type = '设置';
       _options.properties = Object.keys(value.device.message.properties)?.[0];
       _options.properties = Object.keys(value.device.message.properties)?.[0];
     }
     }
+    if (_options.selector === 'tag') {
+      _options.taglist = DeviceModel.selectorValues?.[0]?.value.map((it: any) => ({
+        name: it.column || it.name,
+        type: it.type ? (it.type === 'and' ? '并且' : '或者') : '',
+        value: it.value,
+      }));
+      // console.log(_options.taglist, 'taglist')
+    }
     console.log(_options);
     console.log(_options);
-    console.log('device', item);
-    props.save(item, _options);
+    // console.log('device', item);
+    props.save(item);
+    FormModel.actions[props.name].options = _options;
+    DeviceModel.current = 0;
   };
   };
 
 
   useEffect(() => {
   useEffect(() => {

+ 14 - 4
src/pages/rule-engine/Scene/Save/action/DeviceOutput/model.ts

@@ -10,23 +10,33 @@ type ModelType = {
     content: React.ReactNode;
     content: React.ReactNode;
   }[];
   }[];
   current: number;
   current: number;
-  productId: string[];
-  deviceId: any[];
+  productId: string;
+  deviceId: string;
   productDetail: ProductItem | any;
   productDetail: ProductItem | any;
   device: Partial<ActionsDeviceProps>;
   device: Partial<ActionsDeviceProps>;
   deviceDetail: any;
   deviceDetail: any;
   options: any;
   options: any;
+  selector: string;
+  selectorValues: any;
+  upperKey: string;
+  source: string;
+  relationName: string;
 };
 };
 
 
 const DeviceModel = model<ModelType>({
 const DeviceModel = model<ModelType>({
   steps: [],
   steps: [],
   current: 0,
   current: 0,
-  productId: [],
-  deviceId: [],
+  productId: '',
+  deviceId: '',
   productDetail: {},
   productDetail: {},
   device: {},
   device: {},
   deviceDetail: {},
   deviceDetail: {},
   options: {},
   options: {},
+  selector: 'fixed',
+  selectorValues: [],
+  upperKey: '',
+  source: 'fixed',
+  relationName: '',
 });
 });
 
 
 export default DeviceModel;
 export default DeviceModel;

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

@@ -218,10 +218,10 @@ export default observer(() => {
           tableAlertRender={false}
           tableAlertRender={false}
           rowSelection={{
           rowSelection={{
             type: 'radio',
             type: 'radio',
-            selectedRowKeys: DeviceModel.productId,
+            selectedRowKeys: [DeviceModel.productId],
             onChange: (selectedRowKeys, selectedRows) => {
             onChange: (selectedRowKeys, selectedRows) => {
               // console.log(selectedRowKeys,selectedRows)
               // console.log(selectedRowKeys,selectedRows)
-              DeviceModel.productId = selectedRows.map((item) => item.id);
+              DeviceModel.productId = selectedRows.map((item) => item.id)?.[0];
               DeviceModel.productDetail = selectedRows?.[0];
               DeviceModel.productDetail = selectedRows?.[0];
             },
             },
           }}
           }}

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

@@ -141,6 +141,52 @@ export default (props: ItemProps) => {
     }
     }
   };
   };
 
 
+  const deviceRender = (data: ActionsType | undefined) => {
+    switch (data?.device?.selector) {
+      case 'fixed':
+        return (
+          <div>
+            {data?.options?.type}
+            <span>{data?.options?.name}</span>
+            {data?.options?.properties}
+          </div>
+        );
+      case 'tag':
+        return (
+          <div>
+            {data?.options?.type}
+            {data.options?.taglist.map((item: any) => (
+              <span>
+                {item.type}
+                {item.name}
+                {item.value}
+              </span>
+            ))}
+            {data?.options?.productName}
+            {data?.options?.properties}
+          </div>
+        );
+      case 'relation':
+        return (
+          <div>
+            {data?.options?.type}与<span>{data?.options?.name}</span>具有相同
+            {data?.options?.relationName}的{data?.options?.productName}设备的
+            {data?.options?.properties}
+          </div>
+        );
+      default:
+        return (
+          <AddButton
+            onClick={() => {
+              setVisible(true);
+            }}
+          >
+            点击配置执行动作
+          </AddButton>
+        );
+    }
+  };
+
   const contentRender = () => {
   const contentRender = () => {
     if (props?.data?.alarm?.mode === 'trigger') {
     if (props?.data?.alarm?.mode === 'trigger') {
       return (
       return (
@@ -170,6 +216,8 @@ export default (props: ItemProps) => {
       );
       );
     } else if (props?.data?.executor === 'notify') {
     } else if (props?.data?.executor === 'notify') {
       return notifyRender(props?.data);
       return notifyRender(props?.data);
+    } else if (props?.data?.executor === 'device') {
+      return deviceRender(props?.data);
     }
     }
     return (
     return (
       <AddButton
       <AddButton

+ 12 - 9
src/pages/rule-engine/Scene/Save/action/device/relationSelect.tsx

@@ -4,7 +4,7 @@ import { getRelations } from '@/pages/rule-engine/Scene/Save/action/service';
 
 
 interface RelationProps {
 interface RelationProps {
   value?: any;
   value?: any;
-  onChange?: (value?: any) => void;
+  onChange?: (value?: any, options?: any) => void;
   id?: string;
   id?: string;
 }
 }
 
 
@@ -33,16 +33,19 @@ export default (props: RelationProps) => {
       options={options}
       options={options}
       style={{ width: '100%' }}
       style={{ width: '100%' }}
       value={props.value ? props.value[0]?.value?.relation : undefined}
       value={props.value ? props.value[0]?.value?.relation : undefined}
-      onSelect={(key: string) => {
+      onSelect={(key: string, option: any) => {
         if (props.onChange) {
         if (props.onChange) {
-          props.onChange([
-            {
-              value: {
-                objectType: 'user',
-                relation: key,
+          props.onChange(
+            [
+              {
+                value: {
+                  objectType: 'user',
+                  relation: key,
+                },
               },
               },
-            },
-          ]);
+            ],
+            option,
+          );
         }
         }
       }}
       }}
       placeholder={'请选择关系'}
       placeholder={'请选择关系'}

+ 5 - 3
src/pages/rule-engine/Scene/Save/components/ParamsSelect/index.tsx

@@ -52,9 +52,9 @@ export default (props: Props) => {
     };
     };
   });
   });
 
 
-  useEffect(() => {
-    props.onChange(value, tabKey);
-  }, [value, tabKey]);
+  // useEffect(() => {
+  //   props.onChange(value, tabKey);
+  // }, [value, tabKey]);
 
 
   return (
   return (
     <div className={'select-wrapper'} ref={wrapperRef} style={props.style}>
     <div className={'select-wrapper'} ref={wrapperRef} style={props.style}>
@@ -64,6 +64,7 @@ export default (props: Props) => {
         value={value}
         value={value}
         onChange={(e) => {
         onChange={(e) => {
           setValue(e.target.value);
           setValue(e.target.value);
+          props.onChange(e.target.value, tabKey);
         }}
         }}
         onFocus={() => {
         onFocus={() => {
           setVisible(true);
           setVisible(true);
@@ -87,6 +88,7 @@ export default (props: Props) => {
                     )}
                     )}
                     onClick={() => {
                     onClick={() => {
                       setTabKey(item.key);
                       setTabKey(item.key);
+                      props.onChange(value, item.key);
                     }}
                     }}
                   >
                   >
                     {item.label}
                     {item.label}