wzyyy пре 3 година
родитељ
комит
7269eadc31
26 измењених фајлова са 378 додато и 227 уклоњено
  1. 4 1
      src/pages/device/Instance/Detail/Diagnose/Message/Dialog/index.tsx
  2. 14 1
      src/pages/device/Instance/Detail/Diagnose/Message/index.less
  3. 256 190
      src/pages/device/Instance/Detail/Diagnose/Message/index.tsx
  4. 2 1
      src/pages/device/Instance/Detail/Log/index.tsx
  5. 3 3
      src/pages/device/Instance/Detail/MetadataLog/Property/Detail.tsx
  6. 1 1
      src/pages/device/Instance/Detail/MetadataLog/Property/index.tsx
  7. 1 1
      src/pages/link/AccessConfig/Detail/Cloud/index.tsx
  8. 3 2
      src/pages/link/DataCollect/DataGathering/index.less
  9. 1 1
      src/pages/link/DataCollect/DataGathering/index.tsx
  10. 1 0
      src/pages/link/DataCollect/components/Device/index.tsx
  11. 3 0
      src/pages/link/DataCollect/components/Point/Save/modbus.tsx
  12. 3 0
      src/pages/link/DataCollect/components/Point/Save/opc-ua.tsx
  13. 1 0
      src/pages/link/DataCollect/components/Point/index.tsx
  14. 6 0
      src/pages/link/DataCollect/components/Tree/index.less
  15. 2 0
      src/pages/link/DataCollect/components/Tree/index.tsx
  16. 2 1
      src/pages/link/Type/Detail/index.tsx
  17. 5 5
      src/pages/media/DashBoard/index.tsx
  18. 1 1
      src/pages/rule-engine/Alarm/Configuration/Save/Base/index.tsx
  19. 12 2
      src/pages/rule-engine/Alarm/Configuration/index.tsx
  20. 3 3
      src/pages/rule-engine/Alarm/Configuration/service.ts
  21. 2 5
      src/pages/system/DataSource/Save/index.tsx
  22. 7 2
      src/pages/system/DataSource/index.tsx
  23. 18 1
      src/pages/system/Relationship/Save/index.tsx
  24. 11 1
      src/pages/system/Relationship/index.tsx
  25. 7 1
      src/pages/system/Role/Detail/Permission/index.tsx
  26. 9 4
      src/pages/system/User/Save/index.tsx

+ 4 - 1
src/pages/device/Instance/Detail/Diagnose/Message/Dialog/index.tsx

@@ -50,7 +50,10 @@ const Dialog = (props: Props) => {
             <div className="dialog-box">
               <div className="dialog-header">
                 <div className="dialog-title">
-                  <Badge color={statusColor.get(item.error ? 'error' : 'success')} />
+                  <Badge
+                    color={statusColor.get(item.error ? 'error' : 'success')}
+                    style={{ marginRight: 5 }}
+                  />
                   {operationMap.get(item.operation) || item?.operation}
                 </div>
                 <div className="dialog-time">

+ 14 - 1
src/pages/device/Instance/Detail/Diagnose/Message/index.less

@@ -19,7 +19,20 @@
   padding: 15px;
   background-color: #e7eaec;
 
-  .parameter {
+  .function-item {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+    .function-item-form {
+      width: 80%;
+      min-width: 500px;
+    }
+    .function-item-btn {
+      min-width: 65px;
+    }
+  }
+
+  .inputs-parameter {
     margin: 15px 0;
   }
 }

+ 256 - 190
src/pages/device/Instance/Detail/Diagnose/Message/index.tsx

@@ -1,13 +1,13 @@
 import TitleComponent from '@/components/TitleComponent';
 import './index.less';
 import Dialog from './Dialog';
-import { Badge, Button, Col, DatePicker, Empty, Input, InputNumber, Row, Select } from 'antd';
+import { Badge, Button, Col, Empty, Row } from 'antd';
 import { useEffect, useMemo, useState } from 'react';
 import { InstanceModel, service } from '@/pages/device/Instance';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
 import { map } from 'rxjs/operators';
-import type { Field } from '@formily/core';
-import { createForm, onFieldReact } from '@formily/core';
+import { Field, onFieldReact } from '@formily/core';
+import { createForm, onFieldValueChange } from '@formily/core';
 import { createSchemaField, FormProvider } from '@formily/react';
 import {
   ArrayTable,
@@ -16,6 +16,7 @@ import {
   Input as FInput,
   NumberPicker,
   PreviewText,
+  FormGrid,
   Select as FSelect,
 } from '@formily/antd';
 import { randomString } from '@/utils/util';
@@ -23,33 +24,11 @@ import Log from './Log';
 import { DiagnoseStatusModel, messageStatusMap, messageStyleMap } from '../Status/model';
 import { observer } from '@formily/reactive-react';
 
-// const DataTypeComponent = (value: string) => {
-//   switch (value) {
-//     case 'array':
-//       return <div>{value}array</div>
-//     // case 'enum':
-//     //   return <div>{value}</div>
-//     case 'geo':
-//       return <div>{value}geo</div>
-//     case 'file':
-//       return <div>{value}file</div>
-//     default:
-//       return <div>{value}</div>
-//   }
-// }
-
-const DatePicker1: any = DatePicker;
-
 const Message = observer(() => {
   const [subscribeTopic] = useSendWebsocketMessage();
-  const [type, setType] = useState<'property' | 'function'>('function');
   const [input, setInput] = useState<any>({});
   const [inputs, setInputs] = useState<any[]>([]);
 
-  const [propertyType, setPropertyType] = useState<'read' | 'setting'>('read');
-  const [property, setProperty] = useState<any>({});
-  const [propertyValue, setPropertyValue] = useState<any>('');
-
   const metadata = JSON.parse(InstanceModel.detail?.metadata || '{}');
 
   const subscribeLog = () => {
@@ -130,56 +109,6 @@ const Message = observer(() => {
       });
   };
 
-  const getItemNode = (t: string) => {
-    switch (t) {
-      case 'boolean':
-        return (
-          <Select
-            style={{ width: '100%', textAlign: 'left' }}
-            options={[
-              { label: 'true', value: true },
-              { label: 'false', value: false },
-            ]}
-            placeholder={'请选择'}
-            onChange={(value) => {
-              setPropertyValue(value);
-            }}
-          />
-        );
-      case 'int':
-      case 'long':
-      case 'float':
-      case 'double':
-        return (
-          <InputNumber
-            style={{ width: '100%' }}
-            placeholder={'请输入'}
-            onChange={(value) => {
-              setPropertyValue(value);
-            }}
-          />
-        );
-      case 'date':
-        return (
-          <DatePicker1
-            style={{ width: '100%' }}
-            onChange={(value: any) => {
-              setPropertyValue(value);
-            }}
-          />
-        );
-      default:
-        return (
-          <Input
-            onChange={(e) => {
-              setPropertyValue(e.target.value);
-            }}
-            placeholder="填写属性值"
-            style={{ width: '100%' }}
-          />
-        );
-    }
-  };
   useEffect(() => {
     if (DiagnoseStatusModel.state === 'success') {
       subscribeLog();
@@ -222,81 +151,76 @@ const Message = observer(() => {
     [],
   );
 
-  const dataRender = () => {
-    switch (type) {
-      case 'function':
-        return (
-          <Col span={5}>
-            <Select
-              style={{ width: '100%' }}
-              onChange={(value: any) => {
-                const data = (metadata?.functions || []).find((item: any) => item.id === value);
-                setInput(data);
-                setInputs(data?.inputs || []);
-                form.setValues({
-                  data: data?.inputs || [],
+  const _form = useMemo(
+    () =>
+      createForm({
+        initialValues: {
+          type: 'function',
+        },
+        effects() {
+          onFieldValueChange('property', (field) => {
+            const value = (field as Field).value;
+            const valueType = (metadata?.properties || []).find((it: any) => it.id === value)
+              ?.valueType?.type;
+            const format = field.query('.propertyValue').take() as any;
+            format.setValue('');
+            switch (valueType) {
+              case 'date':
+                format.setComponent(FDatePicker);
+                format.setComponentProps({
+                  placeholder: '请选择',
                 });
-              }}
-            >
-              {(metadata?.functions || []).map((i: any) => (
-                <Select.Option key={i.id} value={i.id}>
-                  {i.name}
-                </Select.Option>
-              ))}
-            </Select>
-          </Col>
-        );
-      case 'property':
-        return (
-          <>
-            <Col span={5}>
-              <Select
-                style={{ width: '100%' }}
-                value={propertyType}
-                placeholder="请选择"
-                onChange={(value: any) => {
-                  setPropertyType(value);
-                }}
-              >
-                <Select.Option value={'read'}>读取属性</Select.Option>
-                <Select.Option value={'setting'}>设置属性</Select.Option>
-              </Select>
-            </Col>
-            <Col span={5}>
-              <Select
-                style={{ width: '100%' }}
-                value={property}
-                placeholder="选择属性"
-                onChange={(value: any) => {
-                  setProperty(value);
-                }}
-              >
-                {(metadata?.properties || []).map((i: any) => (
-                  <Select.Option key={i.id} value={i.id}>
-                    {i.name}
-                  </Select.Option>
-                ))}
-              </Select>
-            </Col>
-            {!!property && propertyType === 'setting' && (
-              <Col span={5}>
-                {getItemNode(
-                  (metadata?.properties || []).find((it: any) => it.id === property)?.valueType
-                    ?.type || '',
-                )}
-              </Col>
-            )}
-          </>
-        );
-      default:
-        return null;
-    }
-  };
+                break;
+              case 'boolean':
+                format.setComponent(FSelect);
+                format.setDataSource([
+                  { label: '是', value: true },
+                  { label: '否', value: false },
+                ]);
+                format.setComponentProps({
+                  placeholder: '请选择',
+                });
+                break;
+              case 'int':
+              case 'long':
+              case 'float':
+              case 'double':
+                format.setComponent(NumberPicker);
+                format.setComponentProps({
+                  placeholder: '请输入',
+                });
+                break;
+              default:
+                format.setComponent(FInput);
+                format.setComponentProps({
+                  placeholder: '请输入',
+                });
+                break;
+            }
+          });
+          onFieldValueChange('function', (field) => {
+            const value = (field as Field).value;
+            setInputs([]);
+            setInput({});
+            if (value) {
+              const data = (metadata?.functions || []).find((item: any) => item.id === value);
+              setInput(data);
+              setInputs(data?.inputs || []);
+              form.setValues({
+                data: data?.inputs || [],
+              });
+            }
+          });
+        },
+      }),
+    [],
+  );
 
   const SchemaField = createSchemaField({
     components: {
       FormItem,
       FInput,
+      FormGrid,
       ArrayTable,
       PreviewText,
       FSelect,
@@ -305,6 +229,147 @@ const Message = observer(() => {
     },
   });
 
+  const _schema = {
+    type: 'object',
+    properties: {
+      grid: {
+        type: 'void',
+        'x-component': 'FormGrid',
+        'x-component-props': {
+          minColumns: [4],
+        },
+        properties: {
+          type: {
+            type: 'string',
+            title: '',
+            'x-decorator': 'FormItem',
+            'x-component': 'FSelect',
+            'x-component-props': {
+              placeholder: '请选择',
+            },
+            enum: [
+              { label: '调用功能', value: 'function' },
+              { label: '操作属性', value: 'property' },
+            ],
+            'x-validator': [
+              {
+                required: true,
+                message: '请选择',
+              },
+            ],
+          },
+          function: {
+            type: 'string',
+            title: '',
+            'x-decorator': 'FormItem',
+            'x-component': 'FSelect',
+            'x-component-props': {
+              placeholder: '请选择',
+            },
+            enum: (metadata?.functions || []).map((item: any) => {
+              return { label: item.name, value: item.id };
+            }),
+            'x-validator': [
+              {
+                required: true,
+                message: '请选择',
+              },
+            ],
+            'x-reactions': [
+              {
+                dependencies: ['.type'],
+                fulfill: {
+                  state: {
+                    visible: '{{$deps[0] === "function"}}',
+                  },
+                },
+              },
+            ],
+          },
+          propertyType: {
+            type: 'string',
+            title: '',
+            'x-decorator': 'FormItem',
+            'x-component': 'FSelect',
+            'x-component-props': {
+              placeholder: '请选择',
+            },
+            enum: [
+              { label: '读取属性', value: 'read' },
+              { label: '设置属性', value: 'setting' },
+            ],
+            'x-validator': [
+              {
+                required: true,
+                message: '请选择',
+              },
+            ],
+            'x-reactions': [
+              {
+                dependencies: ['.type'],
+                fulfill: {
+                  state: {
+                    visible: '{{$deps[0] === "property"}}',
+                  },
+                },
+              },
+            ],
+          },
+          property: {
+            type: 'string',
+            title: '',
+            'x-decorator': 'FormItem',
+            'x-component': 'FSelect',
+            'x-component-props': {
+              placeholder: '请选择属性',
+            },
+            enum: (metadata?.properties || []).map((item: any) => {
+              return { label: item.name, value: item.id };
+            }),
+            'x-validator': [
+              {
+                required: true,
+                message: '请选择属性',
+              },
+            ],
+            'x-reactions': [
+              {
+                dependencies: ['.type'],
+                fulfill: {
+                  state: {
+                    visible: '{{$deps[0] === "property"}}',
+                  },
+                },
+              },
+            ],
+          },
+          propertyValue: {
+            type: 'string',
+            title: '',
+            'x-decorator': 'FormItem',
+            'x-component': 'FInput',
+            'x-validator': [
+              {
+                required: true,
+                message: '改字段必填',
+              },
+            ],
+            'x-reactions': [
+              {
+                dependencies: ['.property', 'propertyType'],
+                fulfill: {
+                  state: {
+                    visible: '{{!!$deps[0] && $deps[1] === "setting"}}',
+                  },
+                },
+              },
+            ],
+          },
+        },
+      },
+    },
+  };
+
   const schema = {
     type: 'object',
     properties: {
@@ -356,7 +421,13 @@ const Message = observer(() => {
                 value: {
                   type: 'string',
                   'x-decorator': 'FormItem',
-                  'x-component': FInput,
+                  'x-component': 'FInput',
+                  'x-validator': [
+                    {
+                      required: true,
+                      message: '改字段必填',
+                    },
+                  ],
                 },
               },
             },
@@ -377,7 +448,7 @@ const Message = observer(() => {
                 return (
                   <Col key={key} span={12}>
                     <div style={messageStyleMap.get(obj.status)} className="message-status">
-                      <Badge status={messageStatusMap.get(obj.status)} />
+                      <Badge status={messageStatusMap.get(obj.status)} style={{ marginRight: 5 }} />
                       {obj.text}
                     </div>
                   </Col>
@@ -395,53 +466,48 @@ const Message = observer(() => {
               </div>
             </div>
             <div className="function">
-              <Row gutter={24}>
-                <Col span={5}>
-                  <Select
-                    value={type}
-                    placeholder="请选择"
-                    style={{ width: '100%' }}
-                    onChange={(value) => {
-                      setType(value);
-                      setInputs([]);
-                      setInput({});
-                    }}
-                  >
-                    <Select.Option value="function">调用功能</Select.Option>
-                    <Select.Option value="property">操作属性</Select.Option>
-                  </Select>
-                </Col>
-                {dataRender()}
-                <Col span={3}>
-                  <Button
-                    type="primary"
-                    onClick={async () => {
-                      if (type === 'function') {
-                        const list = (form?.values?.data || []).filter((it) => !!it.value);
-                        const obj = {};
-                        list.map((it) => {
-                          obj[it.id] = it.value;
-                        });
-                        await service.executeFunctions(InstanceModel.detail?.id || '', input.id, {
-                          ...obj,
-                        });
+              <div className={'function-item'}>
+                <div className={'function-item-form'}>
+                  <FormProvider form={_form}>
+                    <SchemaField schema={_schema} />
+                  </FormProvider>
+                </div>
+                <Button
+                  type="primary"
+                  className={'function-item-btn'}
+                  onClick={async () => {
+                    const values = await _form.submit<any>();
+                    let _inputs = undefined;
+                    if (inputs.length) {
+                      _inputs = await form.submit<any>();
+                    }
+                    if (values.type === 'function') {
+                      const list = (_inputs?.data || []).filter((it: any) => !!it.value);
+                      const obj = {};
+                      list.map((it: any) => {
+                        obj[it.id] = it.value;
+                      });
+                      await service.executeFunctions(InstanceModel.detail?.id || '', input.id, {
+                        ...obj,
+                      });
+                    } else {
+                      if (values.propertyType === 'read') {
+                        await service.readProperties(InstanceModel.detail?.id || '', [
+                          values.property,
+                        ]);
                       } else {
-                        if (propertyType === 'read') {
-                          await service.readProperties(InstanceModel.detail?.id || '', [property]);
-                        } else {
-                          await service.settingProperties(InstanceModel.detail?.id || '', {
-                            [property]: propertyValue,
-                          });
-                        }
+                        await service.settingProperties(InstanceModel.detail?.id || '', {
+                          [values.property]: values.propertyValue,
+                        });
                       }
-                    }}
-                  >
-                    发送
-                  </Button>
-                </Col>
-              </Row>
+                    }
+                  }}
+                >
+                  发送
+                </Button>
+              </div>
               {inputs.length > 0 && (
-                <div className="parameter">
+                <div className="inputs-parameter">
                   <h4>功能参数</h4>
                   <FormProvider form={form}>
                     <SchemaField schema={schema} />

+ 2 - 1
src/pages/device/Instance/Detail/Log/index.tsx

@@ -80,7 +80,7 @@ const Log = () => {
   ];
 
   return (
-    <Card className={'device-detail-log'} style={{ minHeight }}>
+    <Card className={'device-detail-log'} style={{ minHeight }} bodyStyle={{ padding: 0 }}>
       <SearchComponent<LogItem>
         field={[...columns]}
         target="logs"
@@ -108,6 +108,7 @@ const Log = () => {
         pagination={{
           pageSize: 10,
         }}
+        style={{ padding: '0 24px' }}
         request={async (params, sort) => {
           let sorts;
           if (sort.timestamp) {

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

@@ -23,7 +23,7 @@ const Detail = (props: Props) => {
                 displayDataTypes={false}
                 style={{ marginTop: 10 }}
                 name={false}
-                src={value}
+                src={value?.formatValue}
               />
             }
           </div>
@@ -33,14 +33,14 @@ const Detail = (props: Props) => {
       return (
         <div>
           <div>自定义属性</div>
-          <Input.TextArea value={value} rows={3} />
+          <Input.TextArea value={value?.formatValue} rows={3} />
         </div>
       );
     } else {
       return (
         <div>
           <div>自定义属性</div>
-          <Input value={value} disabled />
+          <Input value={value?.formatValue} disabled />
         </div>
       );
     }

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

@@ -93,7 +93,7 @@ const PropertyLog = (props: Props) => {
             <SearchOutlined
               onClick={() => {
                 setDetailVisible(true);
-                setCurrent(record.value);
+                setCurrent(record);
               }}
             />
           )}

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

@@ -81,7 +81,7 @@ const Cloud = (props: Props) => {
             provider={props.provider}
             data={props.data}
             config={{
-              config,
+              ...config,
               protocol: protocolCurrent,
             }}
             prev={prev}

+ 3 - 2
src/pages/link/DataCollect/DataGathering/index.less

@@ -3,8 +3,9 @@
   min-height: calc(100vh - 180px);
   .left {
     width: 300px;
-    margin-right: 20px;
-    padding: 10px;
+    margin-top: 24px;
+    margin-right: 12px;
+    padding-right: 10px;
     border-right: 1px solid #eee;
   }
   .right {

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

@@ -46,7 +46,7 @@ export default observer(() => {
 
   return (
     <PageContainer>
-      <Card bordered={false}>
+      <Card bordered={false} bodyStyle={{ paddingTop: 0 }}>
         <div className={styles.container}>
           <div className={styles.left}>
             <ChannelTree

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

@@ -219,6 +219,7 @@ export default observer((props: Props) => {
         loading={loading}
         style={{ minHeight, position: 'relative' }}
         className={'data-collect-collector'}
+        bodyStyle={{ paddingTop: !props.type ? 4 : 24 }}
       >
         <div>
           <div style={{ paddingBottom: 48, height: '100%' }}>

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

@@ -355,6 +355,9 @@ export default (props: Props) => {
             'x-decorator': 'FormItem',
             'x-decorator-props': {
               gridSpan: 2,
+              style: {
+                marginBottom: 8,
+              },
             },
             default: 3000,
             'x-component-props': {

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

@@ -166,6 +166,9 @@ export default (props: Props) => {
             'x-decorator': 'FormItem',
             'x-decorator-props': {
               gridSpan: 2,
+              style: {
+                marginBottom: 8,
+              },
             },
             default: 3000,
             'x-component-props': {

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

@@ -212,6 +212,7 @@ const PointCard = observer((props: PointCardProps) => {
         bordered={false}
         className={'data-collect-point'}
         style={{ position: 'relative', minHeight }}
+        bodyStyle={{ paddingTop: !props.type ? 4 : 24 }}
       >
         <div>
           <div style={{ height: '100%', paddingBottom: 48 }}>

+ 6 - 0
src/pages/link/DataCollect/components/Tree/index.less

@@ -1,3 +1,9 @@
+.data-collect-tree {
+  :global(.ant-tree-node-selected) {
+    background-color: rgba(47, 84, 235, 0.06) !important;
+  }
+}
+
 .treeTitle {
   display: flex;
   align-items: center;

+ 2 - 0
src/pages/link/DataCollect/components/Tree/index.tsx

@@ -139,7 +139,9 @@ export default observer((props: Props) => {
         {TreeModel.dataSource.length ? (
           <Tree
             style={{ overflow: 'hidden' }}
+            className={styles['data-collect-tree']}
             showIcon
+            height={500}
             selectedKeys={TreeModel.selectedKeys}
             switcherIcon={<DownOutlined />}
           >

+ 2 - 1
src/pages/link/Type/Detail/index.tsx

@@ -598,7 +598,8 @@ const Save = observer(() => {
           dependencies: ['type'],
           fulfill: {
             state: {
-              title: '{{$deps[0] === "TCP_SERVER" ? "开启TLS" : "开启DTLS"}}',
+              title:
+                '{{!["TCP_SERVER", "UDP", "COAP_SERVER"].includes($deps[0]) ? "开启TLS" : "开启DTLS"}}',
             },
           },
         },

+ 5 - 5
src/pages/media/DashBoard/index.tsx

@@ -141,11 +141,11 @@ export default () => {
           type: 'value',
           // minInterval: 1,
         },
-        // grid: {
-        //   left: '4%',
-        //   right: '2%',
-        //   top: '2%',
-        // },
+        grid: {
+          left: 0,
+          right: 0,
+          top: '2%',
+        },
         color: ['#2F54EB'],
         series: [
           {

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

@@ -117,8 +117,8 @@ export default () => {
   });
 
   const handleSave = async () => {
-    setLoading(true);
     const data: any = await form.submit();
+    setLoading(true);
     const resp: any = await service.update({ ...data });
     setLoading(false);
     if (resp.status === 200) {

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

@@ -196,7 +196,12 @@ const Configuration = () => {
               disabled: record.state?.value === 'disabled',
               title: '确认手动触发?',
               onConfirm: async () => {
-                await service._execute(record.sceneId);
+                const scene = (record?.scene || [])
+                  .filter((item: any) => item?.triggerType === 'manual')
+                  .map((i) => {
+                    return { id: i?.id };
+                  });
+                await service._execute(scene);
                 onlyMessage(
                   intl.formatMessage({
                     id: 'pages.data.option.success',
@@ -334,7 +339,12 @@ const Configuration = () => {
                     title: '确认手动触发?',
                     disabled: record.state?.value === 'disabled',
                     onConfirm: async () => {
-                      await service._execute(record.sceneId);
+                      const scene = (record?.scene || [])
+                        .filter((item: any) => item?.triggerType === 'manual')
+                        .map((i: any) => {
+                          return { id: i?.id };
+                        });
+                      await service._execute(scene);
                       onlyMessage(
                         intl.formatMessage({
                           id: 'pages.data.option.success',

+ 3 - 3
src/pages/rule-engine/Alarm/Configuration/service.ts

@@ -33,10 +33,10 @@ class Service extends BaseService<ConfigItem> {
     request(`/${SystemConst.API_BASE}/alarm/config/${id}/_disable`, {
       method: 'POST',
     });
-  public _execute = (id: string) =>
-    request(`/${SystemConst.API_BASE}/scene/${id}/_execute`, {
+  public _execute = (data: any) =>
+    request(`/${SystemConst.API_BASE}/scene/batch/_execute`, {
       method: 'POST',
-      data: {},
+      data,
     });
 
   public getAlarmCountById = (id: string) =>

+ 2 - 5
src/pages/system/DataSource/Save/index.tsx

@@ -96,6 +96,7 @@ const Save = (props: Props) => {
               },
             ],
             required: true,
+            'x-disabled': !!props.data.id,
             enum: Store.get('datasource-type'),
           },
           'shareConfig.url': {
@@ -360,11 +361,7 @@ const Save = (props: Props) => {
         props.close();
       }}
       onOk={() => {
-        if ((props.data.id && props.data.typeId === 'rdb') || !props.data.id) {
-          handleSave();
-        } else {
-          onlyMessage('该类型数据库不可以编辑', 'warning');
-        }
+        handleSave();
       }}
     >
       <Form form={form} layout="vertical">

+ 7 - 2
src/pages/system/DataSource/index.tsx

@@ -139,13 +139,18 @@ const DataSource = observer(() => {
           type="link"
           isPermission={userPermission.manage}
           key="manage"
-          disabled={record.state?.value !== 'enabled'}
+          disabled={record.state?.value !== 'enabled' || record?.typeId === 'rabbitmq'}
           onClick={() => {
             const url = getMenuPathByCode(MENUS_CODE[`system/DataSource/Management`]);
             history.push(`${url}?id=${record.id}`);
           }}
           tooltip={{
-            title: record.state?.value !== 'enabled' ? '请先启用数据源' : '管理',
+            title:
+              record?.typeId === 'rabbitmq'
+                ? '暂不支持管理功能'
+                : record.state?.value !== 'enabled'
+                ? '请先启用数据源'
+                : '管理',
           }}
         >
           <DatabaseOutlined />

+ 18 - 1
src/pages/system/Relationship/Save/index.tsx

@@ -1,6 +1,11 @@
 import { useIntl } from 'umi';
 import type { Field } from '@formily/core';
-import { createForm, onFieldInputValueChange, onFieldValueChange } from '@formily/core';
+import {
+  createForm,
+  onFieldInputValueChange,
+  onFieldValueChange,
+  registerValidateRules,
+} from '@formily/core';
 import { createSchemaField } from '@formily/react';
 import React from 'react';
 import * as ICONS from '@ant-design/icons';
@@ -114,6 +119,14 @@ const Save = (props: Props) => {
     },
   });
 
+  registerValidateRules({
+    validateId(value) {
+      if (!value) return '';
+      const reg = new RegExp('^[0-9a-zA-Z_\\\\-]+$');
+      return reg.exec(value) ? '' : '标识只能由数字、字母、下划线、中划线组成';
+    },
+  });
+
   const schema: ISchema = {
     type: 'object',
     properties: {
@@ -170,6 +183,10 @@ const Save = (props: Props) => {
                 required: true,
                 message: '请输入标识',
               },
+              {
+                validateId: true,
+                message: '标识只能由数字、26个英文字母或者下划线组成',
+              },
             ],
             name: 'relation',
             required: true,

+ 11 - 1
src/pages/system/Relationship/index.tsx

@@ -45,9 +45,19 @@ const Relationship = () => {
       },
     },
     {
-      dataIndex: 'targetTypeName',
+      dataIndex: 'targetType',
       title: '被关联方',
       ellipsis: true,
+      valueType: 'select',
+      render: (_, row) => {
+        return row.targetTypeName;
+      },
+      valueEnum: {
+        user: {
+          text: '用户',
+          status: 'user',
+        },
+      },
     },
     {
       dataIndex: 'description',

+ 7 - 1
src/pages/system/Role/Detail/Permission/index.tsx

@@ -97,7 +97,13 @@ const Permission = () => {
               <Form.Item
                 label="名称"
                 name="name"
-                rules={[{ required: true, message: '请输入名称!' }]}
+                rules={[
+                  { required: true, message: '请输入名称!' },
+                  {
+                    max: 64,
+                    message: '最多可输入64个字符',
+                  },
+                ]}
               >
                 <Input />
               </Form.Item>

+ 9 - 4
src/pages/system/User/Save/index.tsx

@@ -338,8 +338,10 @@ const Save = (props: Props) => {
               gridSpan: 1,
               addonAfter: (
                 <PermissionButton
-                  type="link"
-                  style={{ padding: 0 }}
+                  // type="link"
+                  type="primary"
+                  ghost
+                  style={{ padding: '0 8px' }}
                   isPermission={rolePermission.add}
                   onClick={() => {
                     const tab: any = window.open(`${origin}/#/system/role?save=true`);
@@ -383,8 +385,11 @@ const Save = (props: Props) => {
               gridSpan: 1,
               addonAfter: (
                 <PermissionButton
-                  type="link"
-                  style={{ padding: 0 }}
+                  // type="link"
+                  // style={{ padding: 0 }}
+                  type="primary"
+                  ghost
+                  style={{ padding: '0 8px' }}
                   isPermission={deptPermission.add}
                   onClick={() => {
                     const tab: any = window.open(`${origin}/#/system/department?save=true`);