lind 3 лет назад
Родитель
Сommit
36c0938909

+ 4 - 8
src/pages/rule-engine/Scene/Save/action/VariableItems/builtIn.tsx

@@ -4,7 +4,6 @@ import { useRequest } from 'umi';
 import { queryBuiltInParams } from '@/pages/rule-engine/Scene/Save/action/service';
 import { ItemGroup } from '@/pages/rule-engine/Scene/Save/components';
 import moment from 'moment';
-import { debounce } from 'lodash';
 
 type ChangeType = {
   source?: string;
@@ -58,7 +57,6 @@ export default (props: BuiltInProps) => {
     if (_upperKey) {
       obj.upperKey = _upperKey;
     }
-    console.log(_source, _value);
     if (props.onChange) {
       props.onChange(obj);
     }
@@ -71,10 +69,6 @@ export default (props: BuiltInProps) => {
     [source],
   );
 
-  const inputChange = (e: any) => {
-    itemOnChange(e.target.value);
-  };
-
   return (
     <ItemGroup compact>
       <Select
@@ -122,9 +116,11 @@ export default (props: BuiltInProps) => {
               />
             ) : (
               <Input
-                value={value}
+                value={props.value?.value}
                 placeholder={`请输入${props.data.name}`}
-                onChange={debounce(inputChange, 300)}
+                onChange={(e) => {
+                  onChange(source, e.target.value);
+                }}
               />
             )
           }

+ 23 - 0
src/pages/rule-engine/Scene/Save/components/TimeSelect/index.less

@@ -0,0 +1,23 @@
+@import '~antd/es/style/themes/default.less';
+
+.time-select {
+  display: flex;
+  gap: 4px;
+  align-items: center;
+  width: 100%;
+  height: 32px;
+  padding: 4px 6px;
+  background-color: #fff;
+  border: 1px solid @border-color-base;
+  border-radius: @border-radius-base;
+
+  .time-select-content {
+    flex-grow: 1;
+    width: 0;
+  }
+
+  &:hover,
+  &:focus {
+    border-color: @primary-color-hover;
+  }
+}

+ 88 - 33
src/pages/rule-engine/Scene/Save/components/TimeSelect/index.tsx

@@ -1,63 +1,118 @@
-import { TreeSelect } from 'antd';
+import { Dropdown, Menu } from 'antd';
 import React, { useCallback, useEffect, useState } from 'react';
+import classNames from 'classnames';
+import { DownOutlined } from '@ant-design/icons';
+import './index.less';
 
-interface TimeSelectProps {
-  options?: any[];
-  value?: any[];
-  onChange?: (value: any[]) => void;
+type OptionItemType = {
+  label: string;
+  value: number;
+};
+
+interface TimeSelect {
+  value?: number[];
+  onChange?: (value: number[]) => void;
+  options?: OptionItemType[];
+  className?: string;
   style?: React.CSSProperties;
 }
 
-export default (props: TimeSelectProps) => {
-  const [checkedKeys, setCheckedKeys] = useState<any[]>([]);
+export default (props: TimeSelect) => {
+  const [checkedKeys, setCheckedKeys] = useState<any[]>(props.value || []);
+  const [checkedNames, setCheckedNames] = useState<string[]>([]);
+  const [visible, setVisible] = useState(false);
 
-  const propsChange = (keys: number[]) => {
+  const onchange = (keys: (number | string)[]) => {
     if (props.onChange) {
-      props.onChange(keys);
+      props.onChange(keys.filter((key) => key !== 'null').map(Number));
     }
   };
 
-  const onChange = useCallback(
-    (keys: any[], _, extra) => {
-      if (extra.triggerValue === 'all') {
-        propsChange(extra.checked ? props.options!.map((item: any) => item.value) : []);
+  const onclick = useCallback(
+    ({ key, domEvent }: any) => {
+      domEvent.stopPropagation();
+      const isSelected = checkedKeys.includes(key);
+      if (key === 'null') {
+        onchange(isSelected ? [] : props.options!.map((item) => item.value));
       } else {
-        const noAllKeys = keys.filter((key) => key !== 'all');
-        propsChange(noAllKeys);
+        const Keys = isSelected
+          ? checkedKeys.filter((_key) => _key !== key)
+          : [...checkedKeys, key];
+        const noAllKeys = Keys.filter((item) => item !== 'null');
+        onchange(noAllKeys);
       }
     },
     [checkedKeys, props.options],
   );
 
   useEffect(() => {
-    setCheckedKeys(props.value || []);
     if (props.value && props.options) {
       if (props.value.length >= props.options.length) {
-        setCheckedKeys([...props.value, 'all']);
+        setCheckedKeys([...props.value, 'null'].map(String));
+        setCheckedNames([...props.options.map((item) => item.label), '全部']);
       } else {
-        setCheckedKeys(props.value);
+        setCheckedKeys(props.value.map(String));
+        const selectedItems = props.options.filter((item) => {
+          return props.value!.some((b) => item.value === b);
+        });
+        setCheckedNames(selectedItems.map((item) => item.label));
       }
     } else {
       setCheckedKeys([]);
+      setCheckedNames([]);
     }
   }, [props.value, props.options]);
 
+  const menu = (
+    <Menu multiple={true} selectedKeys={checkedKeys} onClick={onclick}>
+      <Menu.Item key={'null'}>全部</Menu.Item>
+      {props.options &&
+        props.options.map((item) => <Menu.Item key={item.value}>{item.label}</Menu.Item>)}
+    </Menu>
+  );
+
+  useEffect(() => {
+    document.body.onclick = (e) => {
+      const elem: any = e.target;
+      const isSelectDom = elem && elem.className.includes('time-select');
+
+      if (!isSelectDom) {
+        setVisible(false);
+      }
+    };
+    return () => {
+      document.body.onclick = null;
+    };
+  }, []);
+
   return (
-    <TreeSelect
-      treeCheckable
-      value={checkedKeys}
-      onChange={onChange}
-      style={props.style}
-      maxTagCount={0}
-      placeholder={'请选择时间'}
-      maxTagPlaceholder={(values) => {
-        return <span className={''}>{values.map((item) => item.label).toString()}</span>;
+    <Dropdown
+      overlay={menu}
+      overlayStyle={{
+        maxHeight: 300,
+        overflowY: 'auto',
       }}
-      treeData={
-        props.options && props.options.length
-          ? [{ label: '全部', value: 'all' }, ...props.options]
-          : []
-      }
-    />
+      visible={visible}
+      getPopupContainer={() => document.querySelector('#timeSelect')!}
+    >
+      <div
+        className={classNames('time-select', props.className)}
+        style={props.style}
+        onClick={(e) => {
+          e.stopPropagation();
+          setVisible(!visible);
+        }}
+        id={'timeSelect'}
+      >
+        <div className={'time-select-content ellipsis'}>
+          {checkedNames.length ? (
+            checkedNames.toString()
+          ) : (
+            <span style={{ color: 'rgba(0,0,0,.3)' }}>请选择时间</span>
+          )}
+        </div>
+        <DownOutlined />
+      </div>
+    </Dropdown>
   );
 };

+ 2 - 2
src/pages/rule-engine/Scene/Save/components/TimingTrigger/index.tsx

@@ -194,10 +194,10 @@ export default (props: TimingTrigger) => {
               />
               {data.mod === PeriodModEnum.period ? (
                 <TimePicker.RangePicker
-                  format={'hh:mm:ss'}
+                  format={'HH:mm:ss'}
                   value={
                     data.period?.from
-                      ? [moment(data.period?.from, 'hh:mm:ss'), moment(data.period?.to, 'hh:mm:ss')]
+                      ? [moment(data.period?.from, 'HH:mm:ss'), moment(data.period?.to, 'hh:mm:ss')]
                       : undefined
                   }
                   onChange={(_, dateString) => {

+ 6 - 0
src/pages/rule-engine/Scene/Save/components/TriggerWay/index.less

@@ -38,4 +38,10 @@
       border-color: @primary-color-active;
     }
   }
+
+  &.disabled {
+    .trigger-way-item {
+      cursor: not-allowed;
+    }
+  }
 }

+ 7 - 4
src/pages/rule-engine/Scene/Save/components/TriggerWay/index.tsx

@@ -7,6 +7,7 @@ interface TriggerWayProps {
   className?: string;
   onChange?: (type: string) => void;
   onSelect?: (type: string) => void;
+  disabled?: boolean;
 }
 
 export enum TriggerWayType {
@@ -26,15 +27,17 @@ export default (props: TriggerWayProps) => {
   }, [props.value]);
 
   const onSelect = (_type: string) => {
-    setType(_type);
+    if (!props.disabled) {
+      setType(_type);
 
-    if (props.onChange) {
-      props.onChange(_type);
+      if (props.onChange) {
+        props.onChange(_type);
+      }
     }
   };
 
   return (
-    <div className={classNames('trigger-way-warp', props.className)}>
+    <div className={classNames('trigger-way-warp', props.className, { disabled: props.disabled })}>
       <div
         className={classNames('trigger-way-item', {
           active: type === TriggerWayType.manual,

+ 3 - 1
src/pages/rule-engine/Scene/Save/index.tsx

@@ -54,10 +54,12 @@ export default () => {
   const [shakeLimit, setShakeLimit] = useState<ShakeLimitType>(DefaultShakeLimit);
   const [requestParams, setRequestParams] = useState<any>(undefined);
   const [actionsData, setActionsData] = useState<any[]>([]);
+  const [isEdit, setIsEdit] = useState(false);
 
   const getDetail = async (id: string) => {
     const resp = await service.detail(id);
     if (resp.status === 200 && resp.result) {
+      setIsEdit(true);
       const _data: any = resp.result;
       FormModel = _data;
       form.setFieldsValue(_data);
@@ -209,7 +211,7 @@ export default () => {
               name={['trigger', 'type']}
               rules={[{ required: true, message: '请选择触发方式' }]}
             >
-              <TriggerWay onSelect={setTriggerType} />
+              <TriggerWay onSelect={setTriggerType} disabled={isEdit} />
             </Form.Item>
             {triggerType === TriggerWayType.timing && (
               <Form.Item name={['trigger', 'timer']}>

+ 1 - 0
src/pages/rule-engine/Scene/Save/trigger/index.tsx

@@ -1,3 +1,4 @@
+// 已废弃
 import { useCallback, useEffect, useState } from 'react';
 import type { FormInstance } from 'antd';
 import { Col, Form, Row, Select, TreeSelect } from 'antd';

+ 1 - 1
src/pages/rule-engine/Scene/index.tsx

@@ -63,7 +63,7 @@ const Scene = () => {
           })}
       </PermissionButton>,
       <PermissionButton
-        key={'update'}
+        key={'started'}
         type={'link'}
         style={{ padding: 0 }}
         isPermission={permission.action}