|
|
@@ -1,5 +1,17 @@
|
|
|
import { PageContainer } from '@ant-design/pro-layout';
|
|
|
-import { Button, Card, Form, Input, InputNumber, Radio, Space, Switch, Tooltip } from 'antd';
|
|
|
+import {
|
|
|
+ Button,
|
|
|
+ Card,
|
|
|
+ Col,
|
|
|
+ Form,
|
|
|
+ Input,
|
|
|
+ InputNumber,
|
|
|
+ Radio,
|
|
|
+ Row,
|
|
|
+ Space,
|
|
|
+ Switch,
|
|
|
+ Tooltip,
|
|
|
+} from 'antd';
|
|
|
import { useIntl, useLocation } from 'umi';
|
|
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
import { PermissionButton, TitleComponent } from '@/components';
|
|
|
@@ -14,6 +26,7 @@ import './index.less';
|
|
|
import { model } from '@formily/reactive';
|
|
|
import type { FormModelType } from '@/pages/rule-engine/Scene/typings';
|
|
|
import { onlyMessage } from '@/utils/util';
|
|
|
+import Explanation from './Explanation';
|
|
|
|
|
|
type ShakeLimitType = {
|
|
|
enabled: boolean;
|
|
|
@@ -196,181 +209,199 @@ export default () => {
|
|
|
return (
|
|
|
<PageContainer>
|
|
|
<Card>
|
|
|
- <Form
|
|
|
- scrollToFirstError={{
|
|
|
- behavior: 'smooth',
|
|
|
- block: 'end',
|
|
|
- }}
|
|
|
- form={form}
|
|
|
- colon={false}
|
|
|
- name="basicForm"
|
|
|
- layout={'vertical'}
|
|
|
- preserve={false}
|
|
|
- className={'scene-save'}
|
|
|
- initialValues={{
|
|
|
- actions: [undefined],
|
|
|
- }}
|
|
|
- onValuesChange={(changeValue, allValues) => {
|
|
|
- if (changeValue.trigger) {
|
|
|
- if (changeValue.trigger.device) {
|
|
|
- if (
|
|
|
- changeValue.trigger.device.productId ||
|
|
|
- changeValue.trigger.device.selectorValues ||
|
|
|
- (changeValue.trigger.device.operation &&
|
|
|
- hasKeyInObject(
|
|
|
- ['operator', 'eventId', 'functionId'],
|
|
|
- changeValue.trigger.device.operation,
|
|
|
- ))
|
|
|
- ) {
|
|
|
- setTriggerValue([]);
|
|
|
- setRequestParams({ trigger: allValues.trigger });
|
|
|
- setTriggerDatas(allValues.trigger);
|
|
|
- }
|
|
|
+ <Row>
|
|
|
+ <Col span={16}>
|
|
|
+ <Form
|
|
|
+ scrollToFirstError={{
|
|
|
+ behavior: 'smooth',
|
|
|
+ block: 'end',
|
|
|
+ }}
|
|
|
+ form={form}
|
|
|
+ colon={false}
|
|
|
+ name="basicForm"
|
|
|
+ layout={'vertical'}
|
|
|
+ preserve={false}
|
|
|
+ className={'scene-save'}
|
|
|
+ initialValues={{
|
|
|
+ actions: [undefined],
|
|
|
+ }}
|
|
|
+ onValuesChange={(changeValue, allValues) => {
|
|
|
+ if (changeValue.trigger) {
|
|
|
+ if (changeValue.trigger.device) {
|
|
|
+ if (
|
|
|
+ changeValue.trigger.device.productId ||
|
|
|
+ changeValue.trigger.device.selectorValues ||
|
|
|
+ (changeValue.trigger.device.operation &&
|
|
|
+ hasKeyInObject(
|
|
|
+ ['operator', 'eventId', 'functionId'],
|
|
|
+ changeValue.trigger.device.operation,
|
|
|
+ ))
|
|
|
+ ) {
|
|
|
+ setTriggerValue([]);
|
|
|
+ setRequestParams({ trigger: allValues.trigger });
|
|
|
+ setTriggerDatas(allValues.trigger);
|
|
|
+ }
|
|
|
|
|
|
- if (
|
|
|
- hasKeyInObject(['productId'], changeValue.trigger.device) ||
|
|
|
- (changeValue.trigger.device.operation &&
|
|
|
- hasKeyInObject(
|
|
|
- ['operator', 'eventId', 'functionId'],
|
|
|
- changeValue.trigger.device.operation,
|
|
|
- ))
|
|
|
- ) {
|
|
|
- setActionParams({ trigger: allValues.trigger }); // 用于内置参数请求
|
|
|
+ if (
|
|
|
+ hasKeyInObject(['productId'], changeValue.trigger.device) ||
|
|
|
+ (changeValue.trigger.device.operation &&
|
|
|
+ hasKeyInObject(
|
|
|
+ ['operator', 'eventId', 'functionId'],
|
|
|
+ changeValue.trigger.device.operation,
|
|
|
+ ))
|
|
|
+ ) {
|
|
|
+ setActionParams({ trigger: allValues.trigger }); // 用于内置参数请求
|
|
|
+ }
|
|
|
+ } else if (['timer', 'manual'].includes(changeValue.trigger.type)) {
|
|
|
+ setActionParams({ trigger: allValues.trigger }); // 用于内置参数请求
|
|
|
+ }
|
|
|
}
|
|
|
- } else if (['timer', 'manual'].includes(changeValue.trigger.type)) {
|
|
|
- setActionParams({ trigger: allValues.trigger }); // 用于内置参数请求
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- if (allValues.actions) {
|
|
|
- setActionsData(allValues.actions);
|
|
|
- }
|
|
|
- FormModel = { ...allValues };
|
|
|
- }}
|
|
|
- >
|
|
|
- <Form.Item
|
|
|
- name={'name'}
|
|
|
- label={<TitleComponent data={'名称'} style={{ margin: 0 }} />}
|
|
|
- rules={[
|
|
|
- { required: true, message: '请输入名称' },
|
|
|
- {
|
|
|
- max: 64,
|
|
|
- message: intl.formatMessage({
|
|
|
- id: 'pages.form.tip.max64',
|
|
|
- defaultMessage: '最多输入64个字符',
|
|
|
- }),
|
|
|
- },
|
|
|
- ]}
|
|
|
- >
|
|
|
- <Input placeholder={'请输入名称'} />
|
|
|
- </Form.Item>
|
|
|
- <Form.Item label={<TitleComponent data={'触发方式'} style={{ margin: 0 }} />} required>
|
|
|
- <Form.Item
|
|
|
- name={['trigger', 'type']}
|
|
|
- rules={[{ required: true, message: '请选择触发方式' }]}
|
|
|
+ if (allValues.actions) {
|
|
|
+ setActionsData(allValues.actions);
|
|
|
+ }
|
|
|
+ FormModel = { ...allValues };
|
|
|
+ }}
|
|
|
>
|
|
|
- <TriggerWay onSelect={setTriggerType} disabled={isEdit} />
|
|
|
- </Form.Item>
|
|
|
- {triggerType === TriggerWayType.timing && (
|
|
|
- <TimingTrigger name={['trigger']} form={form} className={'trigger-type-content'} />
|
|
|
- )}
|
|
|
- {triggerType === TriggerWayType.device && (
|
|
|
- <TriggerDevice value={triggerDatas} className={'trigger-type-content'} form={form} />
|
|
|
- )}
|
|
|
- </Form.Item>
|
|
|
- {triggerType === TriggerWayType.device &&
|
|
|
- requestParams &&
|
|
|
- requestParams.trigger?.device?.productId ? (
|
|
|
- <Form.Item label={AntiShake}>
|
|
|
- <TriggerTerm ref={triggerRef} params={requestParams} value={triggerValue} />
|
|
|
- </Form.Item>
|
|
|
- ) : null}
|
|
|
- <Form.Item hidden name={'parallel'} initialValue={true}>
|
|
|
- <Input />
|
|
|
- </Form.Item>
|
|
|
- <Form.Item
|
|
|
- label={
|
|
|
- <Space>
|
|
|
- <TitleComponent data={<span>执行动作</span>} style={{ margin: 0 }} />
|
|
|
- <Tooltip
|
|
|
- title={
|
|
|
- <div>
|
|
|
- <div>串行:按顺序依次执行动作</div>
|
|
|
- <div>并行:同时执行所有动作</div>
|
|
|
- </div>
|
|
|
- }
|
|
|
+ <Form.Item
|
|
|
+ name={'name'}
|
|
|
+ label={<TitleComponent data={'名称'} style={{ margin: 0 }} />}
|
|
|
+ rules={[
|
|
|
+ { required: true, message: '请输入名称' },
|
|
|
+ {
|
|
|
+ max: 64,
|
|
|
+ message: intl.formatMessage({
|
|
|
+ id: 'pages.form.tip.max64',
|
|
|
+ defaultMessage: '最多输入64个字符',
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ >
|
|
|
+ <Input placeholder={'请输入名称'} />
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item
|
|
|
+ label={<TitleComponent data={'触发方式'} style={{ margin: 0 }} />}
|
|
|
+ required
|
|
|
+ >
|
|
|
+ <Form.Item
|
|
|
+ name={['trigger', 'type']}
|
|
|
+ rules={[{ required: true, message: '请选择触发方式' }]}
|
|
|
>
|
|
|
- <QuestionCircleOutlined style={{ margin: '0 8px', fontSize: 14 }} />
|
|
|
- </Tooltip>
|
|
|
- <Radio.Group
|
|
|
- value={parallel}
|
|
|
- options={[
|
|
|
- { label: '串行', value: false },
|
|
|
- { label: '并行', value: true },
|
|
|
- ]}
|
|
|
- optionType="button"
|
|
|
- onChange={(e) => {
|
|
|
- setParallel(e.target.value);
|
|
|
- form.setFieldsValue({ parallel: e.target.value });
|
|
|
- }}
|
|
|
- ></Radio.Group>
|
|
|
- </Space>
|
|
|
- }
|
|
|
- >
|
|
|
- <Form.List name="actions">
|
|
|
- {(fields, { add, remove }, { errors }) => (
|
|
|
- <>
|
|
|
- <div className={'scene-actions'} style={{ paddingBottom: 24 }}>
|
|
|
- {fields.map(({ key, name, ...restField }) => (
|
|
|
- <ActionItems
|
|
|
- key={key}
|
|
|
- form={form}
|
|
|
- restField={restField}
|
|
|
- name={name}
|
|
|
- trigger={actionParams}
|
|
|
- triggerType={triggerType}
|
|
|
- onRemove={() => remove(name)}
|
|
|
- actionItemData={actionsData.length && actionsData[name]}
|
|
|
- parallel={parallel}
|
|
|
- />
|
|
|
- ))}
|
|
|
- <Form.Item noStyle>
|
|
|
- <Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
|
|
|
- 新增
|
|
|
- </Button>
|
|
|
- </Form.Item>
|
|
|
- </div>
|
|
|
- <Form.ErrorList errors={errors} />
|
|
|
- </>
|
|
|
- )}
|
|
|
- </Form.List>
|
|
|
- </Form.Item>
|
|
|
- <Form.Item
|
|
|
- label={<TitleComponent data={'说明'} style={{ margin: 0 }} />}
|
|
|
- name={'description'}
|
|
|
- >
|
|
|
- <Input.TextArea showCount maxLength={200} placeholder={'请输入说明'} rows={4} />
|
|
|
- </Form.Item>
|
|
|
- {/*{triggerType === TriggerWayType.device &&*/}
|
|
|
- {/*requestParams &&*/}
|
|
|
- {/*requestParams.trigger?.device?.productId ? (*/}
|
|
|
- {/* <Form.Item hidden name={['trigger','shakeLimit']}>*/}
|
|
|
- {/* <Input />*/}
|
|
|
- {/* </Form.Item>*/}
|
|
|
- {/*) : null}*/}
|
|
|
- <Form.Item hidden name={'id'}>
|
|
|
- <Input />
|
|
|
- </Form.Item>
|
|
|
- <PermissionButton
|
|
|
- isPermission={getOtherPermission(['add', 'update'])}
|
|
|
- onClick={saveData}
|
|
|
- type={'primary'}
|
|
|
- loading={loading}
|
|
|
- htmlType="submit"
|
|
|
- >
|
|
|
- 保存
|
|
|
- </PermissionButton>
|
|
|
- </Form>
|
|
|
+ <TriggerWay onSelect={setTriggerType} disabled={isEdit} />
|
|
|
+ </Form.Item>
|
|
|
+ {triggerType === TriggerWayType.timing && (
|
|
|
+ <TimingTrigger
|
|
|
+ name={['trigger']}
|
|
|
+ form={form}
|
|
|
+ className={'trigger-type-content'}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ {triggerType === TriggerWayType.device && (
|
|
|
+ <TriggerDevice
|
|
|
+ value={triggerDatas}
|
|
|
+ className={'trigger-type-content'}
|
|
|
+ form={form}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </Form.Item>
|
|
|
+ {triggerType === TriggerWayType.device &&
|
|
|
+ requestParams &&
|
|
|
+ requestParams.trigger?.device?.productId ? (
|
|
|
+ <Form.Item label={AntiShake}>
|
|
|
+ <TriggerTerm ref={triggerRef} params={requestParams} value={triggerValue} />
|
|
|
+ </Form.Item>
|
|
|
+ ) : null}
|
|
|
+ <Form.Item hidden name={'parallel'} initialValue={true}>
|
|
|
+ <Input />
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item
|
|
|
+ label={
|
|
|
+ <Space>
|
|
|
+ <TitleComponent data={<span>执行动作</span>} style={{ margin: 0 }} />
|
|
|
+ <Tooltip
|
|
|
+ title={
|
|
|
+ <div>
|
|
|
+ <div>串行:按顺序依次执行动作</div>
|
|
|
+ <div>并行:同时执行所有动作</div>
|
|
|
+ </div>
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <QuestionCircleOutlined style={{ margin: '0 8px', fontSize: 14 }} />
|
|
|
+ </Tooltip>
|
|
|
+ <Radio.Group
|
|
|
+ value={parallel}
|
|
|
+ options={[
|
|
|
+ { label: '串行', value: false },
|
|
|
+ { label: '并行', value: true },
|
|
|
+ ]}
|
|
|
+ optionType="button"
|
|
|
+ onChange={(e) => {
|
|
|
+ setParallel(e.target.value);
|
|
|
+ form.setFieldsValue({ parallel: e.target.value });
|
|
|
+ }}
|
|
|
+ ></Radio.Group>
|
|
|
+ </Space>
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <Form.List name="actions">
|
|
|
+ {(fields, { add, remove }, { errors }) => (
|
|
|
+ <>
|
|
|
+ <div className={'scene-actions'} style={{ paddingBottom: 24 }}>
|
|
|
+ {fields.map(({ key, name, ...restField }) => (
|
|
|
+ <ActionItems
|
|
|
+ key={key}
|
|
|
+ form={form}
|
|
|
+ restField={restField}
|
|
|
+ name={name}
|
|
|
+ trigger={actionParams}
|
|
|
+ triggerType={triggerType}
|
|
|
+ onRemove={() => remove(name)}
|
|
|
+ actionItemData={actionsData.length && actionsData[name]}
|
|
|
+ parallel={parallel}
|
|
|
+ />
|
|
|
+ ))}
|
|
|
+ <Form.Item noStyle>
|
|
|
+ <Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
|
|
|
+ 新增
|
|
|
+ </Button>
|
|
|
+ </Form.Item>
|
|
|
+ </div>
|
|
|
+ <Form.ErrorList errors={errors} />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </Form.List>
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item
|
|
|
+ label={<TitleComponent data={'说明'} style={{ margin: 0 }} />}
|
|
|
+ name={'description'}
|
|
|
+ >
|
|
|
+ <Input.TextArea showCount maxLength={200} placeholder={'请输入说明'} rows={4} />
|
|
|
+ </Form.Item>
|
|
|
+ {/*{triggerType === TriggerWayType.device &&*/}
|
|
|
+ {/*requestParams &&*/}
|
|
|
+ {/*requestParams.trigger?.device?.productId ? (*/}
|
|
|
+ {/* <Form.Item hidden name={['trigger','shakeLimit']}>*/}
|
|
|
+ {/* <Input />*/}
|
|
|
+ {/* </Form.Item>*/}
|
|
|
+ {/*) : null}*/}
|
|
|
+ <Form.Item hidden name={'id'}>
|
|
|
+ <Input />
|
|
|
+ </Form.Item>
|
|
|
+ <PermissionButton
|
|
|
+ isPermission={getOtherPermission(['add', 'update'])}
|
|
|
+ onClick={saveData}
|
|
|
+ type={'primary'}
|
|
|
+ loading={loading}
|
|
|
+ htmlType="submit"
|
|
|
+ >
|
|
|
+ 保存
|
|
|
+ </PermissionButton>
|
|
|
+ </Form>
|
|
|
+ </Col>
|
|
|
+ <Col span={8}>
|
|
|
+ <Explanation />
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
</Card>
|
|
|
</PageContainer>
|
|
|
);
|